Enginery
Install
$ gem install enginery
+ $ rbenv rehash
if you are using rbenv
Quick start
Create a new application in ./App/
folder:
$ enginery g App
Create a new application in current folder:
$ enginery g
Generate Controllers:
$ enginery g:c Foo
$ enginery g:c Foo Bar Baz
Generate Routes for Foo
controller:
$ enginery g:r Foo a
$ enginery g:r Foo a b c
Generate Models:
$ enginery g:m Foo
$ enginery g:m Foo Bar Baz
Generate Specs:
$ enginery g:s SomeController some_action
Generate Migrations:
$ enginery m migrationName model:ModelName column:some_column
List Migrations:
$ enginery m:l
Run Migrations:
$ enginery m:up migrationID
$ enginery m:down migrationID
Application structure
- base/
| - models/
| - views/
| - controllers/
` - rear-controllers/
| - helpers/
| - specs/
| - migrations/
| - boot.rb
| - config.rb
` - database.rb
- config/
| - config.yml
` - database.yml
- public/
| - assets/
| - app.css
` - app.js
- tmp/
- var/
| - db/
| - log/
` - pid/
- Rakefile
- Gemfile
- app.rb
- config.ru
Tutorial
Projects |
Controllers |
Routes |
Specs |
Views |
Models |
Migrations |
Admin Interface
Projects
To generate a project simply type:
$ enginery g App
This will create ./App
folder with a ready-to-use application inside.
To generate a new application in current folder simply omit application name:
$ enginery g
Engine
Generated application will use ERB
engine by default.
To generate a project that will use a custom engine, use engine
option followed by a semicolon and the full, case sensitive, name of desired engine:
$ enginery g engine:Slim
This will update your Gemfile
by adding slim
gem and will also update config.yml
by adding engine: :Slim
.
Option name can be shortened down to first letter:
$ enginery g e:Slim
ORM
If your project will use any ORM
, use orm
option followed by a semicolon and the name of desired ORM
:
$ enginery g orm:ActiveRecord
Worth to note - ORM
name are case insensitive and can be shortened to first letter(s):
project using ActiveRecord:
$ enginery g orm:ar
$ enginery g o:ar
project using DataMapper:
$ enginery g orm:dm
$ enginery g o:dm
project using Sequel:
$ enginery g orm:sequel
$ enginery g o:sq
Database
It is also possible to set database connection info. Accepted options:
- db_type (or dbtype)
- db_host (or dbhost)
- db_port (or dbport)
- db_name (or dbname)
- db_user (or dbuser)
- db_pass (or dbpass)
project using MySQL:
$ enginery g dbtype:MySQL
$ enginery g dbtype:mysql
$ enginery g dbtype:m
project using PostgreSQL:
$ enginery g dbtype:postgres
$ enginery g dbtype:p
project using Sqlite:
$ enginery g dbtype:sqlite
$ enginery g dbtype:s
Server/Port/Host
Applications generated by Enginery will use Thin web server by default.
To use another server set server
option.
Server name should be provided in full and is case sensitive:
enginery g server:Puma
enginery g s:Puma
Generated application will listen on 5252 port by default.
To use another port, set port
option:
enginery g server:Unicorn port:2000
enginery g s:Unicorn p:2000
To make application to listen on another host than "localhost", use host
option:
enginery g server:Unicorn port:2000 host:192.168.2.5
enginery g s:Unicorn p:2000 h:192.168.2.5
Format
Enginery also allow to specify format to be used by all controllers / actions.
Ex: to make all actions to serve URLs ending in .html
, use format:html
:
$ enginery g format:html
And of course as per other options, format
can be shortened to first letter too:
$ enginery g f:html
And of course you can pass multiple options:
$ enginery g o:ar e:Slim f:html
[ contents ↑ ]
Controllers
As simple as:
$ enginery g:c Foo
This will create "base/controllers/foo/" folder and "base/controllers/foo_controller.rb" file.
The file will contain controller's setups and the folder will contain controller's actions.
Map
By default the controller will be mapped to its underscored name, that's it:
Foo to /foo
FooBar to /foo_bar
Foo::Bar to /foo/bar
etc.
To generate a controller mapped to a custom location, use the route
option:
$ enginery g:c Foo route:bar
$ enginery g:c Foo r:bar
Setups
When generating a controller without any setups, it will use project-wide ones(passed at project generation), if any.
To generate a controller with custom setups, pass them as options:
$ enginery g:c Foo e:Haml
This will create a controller that will use Haml
engine.
Another option is format:
$ enginery g:c Foo f:html
Multiple
When you need to generate multiple controllers at once just pass their names separated by a space:
$ enginery g:c A B C
This will generate 3 controllers without any setups.
Any passed setups will apply to all generated controllers:
$ enginery g:c A B C e:Haml
Namespaces
When you need a namespaced controller, pass its name as is:
$ enginery g:c Foo::Bar
This will generate Foo
module with Bar
controller inside:
module Foo
class Bar < E
end
end
Worth to note that Bar
controller will be mapped to "/foo/bar" URL.
To map it to another location, use route
option as shown above.
Including modules
If your controller needs extra modules included, use include:
option:
$ enginery g:c Foo include:Bar
$ enginery g:c Foo i:Bar
This will generate Foo
controller with Bar
included:
module Foo < E
include Bar
end
Deleting Controllers
As easy as:
$ enginery delete:c ControllerName
This will remove all controller routes, views, specs and helpers, so use with care.
[ contents ↑ ]
Routes
As simple as:
$ enginery g:route Foo bar
$ enginery g:r Foo bar
where Foo
is the controller name and bar
is the route.
This will create "base/controllers/foo/bar.rb" and "base/views/foo/bar.erb" files.
Mapping
You can provide the URL rather than the action name - it will be automatically converted into action name according to effective path rules:
$ enginery g:r Forum posts/latest
This will create "base/controllers/forum/posts__latest.rb" file with posts__latest
action inside and the "base/views/forum/posts__latest.erb" template file.
See more details on actions mapping.
Setups
Setups provided at route generation will be effective only on generated route:
$ enginery g:c Foo e:Haml
$ enginery g:r Foo bar
$ enginery g:r Foo baz e:Slim
Foo#bar
action will use Haml
engine, as per controller setup.
Foo#baz
action will use Slim
engine instead, as per route setup.
Multiple
To generate multiple routes at once just pass their names separated by spaces:
$ enginery g:r Foo a b c
this will create 3 routes and 3 views.
Worth to note that any provided setups will apply on all and only generated actions.
Deleting Routes
As easy as:
$ enginery delete:r ControllerName route_name
This will remove all route files, views and specs, so use with care.
[ contents ↑ ]
Specs
Specs are generated simultaneously with routes.
It makes sense to generate a spec manually only if it was accidentally lost/damaged.
Note - Enginery uses Specular to build/run specs. Feel free to contribute by adding support for other testing frameworks.
To generate a spec use spec
(or just s
) notation followed by controller name and the route to be tested:
$ enginery g:s Foo bar
This will create base/specs/foo/
with bar_spec.rb
file inside.
To generate multiple specs pass route names separated by a space:
$ enginery g:s Foo a b c
This will generate specs/foo/a_spec.rb
, specs/foo/b_spec.rb
and specs/foo/c_spec.rb
files.
To run a spec use $ rake test:Foo#bar
, where Foo
is the controller name and bar
is the tested route.
To run all specs for Foo
controller use $ rake test:Foo
To run all specs for all controllers use $ rake test
or just $ rake
If the controller is under some namespace, pass the full name, do not worry about ::
, rake
will take care:
$ rake test:Forum::Posts
$ rake test:Forum::Posts
To see all available specs use $ rake -D
[ contents ↑ ]
Views
View generator are triggered every time you generate a route, so it make sense to use it only to create a template that was accidentally damaged/lost.
Invocation:
$ enginery g:v Foo bar
where Foo
is the controller name and bar
is the action to generate view for.
This will create "base/views/foo/bar.[ext]" template, if it does not exists.
[ext] depending on effective template engine.
If template already exists, the generator will simply touch it, without modifying the name/content in any way.
[ contents ↑ ]
Models
Supported ORMs: ActiveRecord
, DataMapper
, Sequel
$ enginery g:model Foo
$ enginery g:m Foo
this will create "base/models/foo.rb" file.
File content will depend on setups passed at project generation:
If we generate a project like this:
$ enginery g orm:ActiveRecord
the:
$ enginery g:m Foo
will result in:
class Foo < ActiveRecord::Base
end
And if the project are generated like this:
$ enginery g orm:DataMapper
the:
$ enginery g:m Foo
will result in:
class Foo
include DataMapper::Resource
property :id, Serial
end
To generate a model on a project without default ORM
, use orm
option at model generation:
$ enginery g:m Foo orm:ActiveRecord
$ enginery g:m Foo orm:ar
$ enginery g:m Foo o:ar
will result in:
class Foo < ActiveRecord::Base
end
and will update your Gemfile by adding corresponding gems, unless they are already there.
Associations
With Enginery you can specify a list of associations at model generation.
Supported associations:
- belongs_to
- has_one
- has_many
- has_and_belongs_to_many
Though associations are passed in ActiveRecord way, they will be automatically adjusted if another ORM used.
enginery g:m State has_many:cities
enginery g:m City belongs_to:state
If you need a through
association simply use :through
option:
enginery g:m Photo has_many:tags:through:tagging
enginery g:m Tag has_many:photos:through:tagging
Multiple
Generating multiple models at once:
$ enginery g:m A B C
$ enginery g:models A B C
Including modules
If your model needs extra modules included, use include:
option:
$ enginery g:m Foo include:Bar
$ enginery g:m Foo i:Bar
This will generate Foo
model with Bar
included:
module Foo < ActiveRecord::Base
include Bar
end
Deleting Models
As easy as:
$ enginery delete:m ModelName
[ contents ↑ ]
Migrations
Supported ORMs: ActiveRecord
, DataMapper
, Sequel
Initial migration for any model are auto-generated alongside with model:
$ enginery g:m Page
this will generate Page
model as well a migration that will create model's table when performed up and drop it when performed down.
Migrations will reside in base/migrations/
folder. The file for Page
model created above will be named 1.[timestamp].initializing-Page-model.rb
Now you can edit it by adding columns you need created alongside with table. You should add them inside up
method or block, depending on used ORM.
If you do not want to edit the file manually, you can automatize this step as well by providing columns at model generation:
$ enginery g:m Page column:name column:about:text
now the "up" section will contain instructions to create the table and 2 columns.
Note: if type omitted, String will be used.
When your migration are ready, run it using its serial number.
Serial number usually are printed when migration are generated.
You can also find it by listing available migrations:
$ enginery m:list
$ enginery m:l
this will display something like:
---=---
1 : initializing-Page-model
created at : [timestamp]
last performed : [none|timestamp]
---=---
where "1" is the serial number and "initializing-Page-model" is the name.
Run migration up:
enginery m:up 1
Run migration down:
enginery m:down 1
Adding columns
To add some column to an existing model simply add new migration that will do this.
To generate a migration use the m
notation followed by migration name, model and column(s):
$ enginery m add-email model:Person column:email
this will output something like:
--- Person model - generating "add-email" migration ---
Serial Number: 2
Run migration up:
enginery m:up 2
this will alter table by adding "email" column of "string" type.
Run migration down:
enginery m:down 2
this will drop "email" column.
Updating Columns
To modify some column type use update_column
option followed by column name and new type:
enginery m update-email model:Person update_column:email:text
this will output something like:
--- Person model - generating "update-email" migration ---
Serial Number: 3
Run migration up:
enginery m:up 3
this will alter table by setting "email" type to "text".
Run migration down:
enginery m:down 3
this will alter table by reverting "email" type to "string".
Renaming Columns
To rename some column type use rename_column
option followed by current column name and new name:
enginery m rename-name model:Person rename_column:name:first_name
this will output something like:
--- Person model - generating "update-name" migration ---
Serial Number: 4
Running migration up will rename "name" column to "first_name":
enginery m:up 4
Running migration down will rename "first_name" back to "name":
enginery m:down 4
Running Migrations
With Enginery you are free to choose what migration(s) to run in multiple ways.
Most obvious one is to provide the serial number of a single migration:
$ enginery m:[up|down] 1
When you need to run multiple migrations pass serial numbers separated by spaces:
$ enginery m:[up|down] 1 4 6
this will run 1st, 4th and 6th migrations.
When you need to run N to M migrations, use N-M notation:
$ enginery m:[up|down] 2-6
this will run 2nd to 6th migrations inclusive.
Important Note: Enginery
will automatically set the running order depending on performed direction - ascending on "up" and descending on "down".
$ enginery m:up 4 2 6
performing order: 2 4 6
$ enginery m:down 4 2 6
performing order: 6 4 2
$ enginery m:up 1-4
performing order: 1 2 3 4
$ enginery m:down 1-4
performing order: 4 3 2 1
To run all outstanding migrations just do not pass any steps.
Perform UP all outstanding migrations:
$ enginery m:up
Perform DOWN all outstanding migrations:
$ enginery m:down
To list available migrations use $ enginery m:list
or just $ enginery m:l
Force Running
Enginery
will keep track of migrations already performed and wont run same migration twice.
However, sometimes you may need to run it anyway due to manual schema modification etc.
In such non-standard cases you can use force
option:
$ enginery m:up:force 1
DataMapper Notes
With DataMapper ORM you have extra rake
tasks "for free", like dm:auto_migrate
, dm:auto_upgrade
, dm:auto_migrate:ModelName
, dm:auto_upgrade:ModelName
Use $ rake -D
to list all tasks.
Note on renaming columns: as of 'dm-migrations' 1.2.0 renaming columns are broken for MySQL adapter. Master branch have it fixed but not yet released.
[ contents ↑ ]
Admin Interface
Enginery
is using Rear
to build a admin interface for generated models.
Admin interface will be automatically mounted at /admin
.
To mount it elsewhere, edit config/config.yml
by updating :admin_url
setting.
To disable admin interface simply remove :admin_url
setting from config/config.yml
.
[ contents ↑ ]
Contributing
- Fork Enginery repository
- optionally create a new branch
- make your changes
- submit a pull request
Issues/Bugs:
github.com/espresso/enginery/issues
Mailing List:
groups.google.com/.../espresso-framework
IRC channel: #espressorb on irc.freenode.net