-
Notifications
You must be signed in to change notification settings - Fork 7
Mounting
Mount controllers in an application class by mount
method:
# foo_controller.rb
module MyProject
class FooController < Flame::Controller
def hello_world
'Hello, world!'
end
def my_name(name, last_name = nil)
"My name is #{name} #{last_name}"
end
end
end
# application.rb
module MyProject
class Application < Flame::Application
mount FooController
## GET '/foo/hello' => `FooController#hello`
## GET '/foo/my_name/:name/:?last_name' => `FooController#my_name`
end
end
Namespace path is a controller class name without Controller
or Ctrl
suffix by default,
but it can be changed via PATH
constant inside controller:
# foo_controller.rb
module MyProject
class FooController < Flame::Controller
PATH = '/bar'
end
end
or at mounting:
# application.rb
module MyProject
class Application < Flame::Application
mount FooController, '/bar'
## GET '/bar/hello' => `FooController#hello`
## GET '/bar/my_name/:name/:?last_name' => `FooController#my_name`
end
end
You can specify controller as its downcased name without suffix as symbol:
# application.rb
module MyProject
class Application < Flame::Application
mount :foo
end
end
By default, paths are the same as methods names and HTTP method is GET
,
but there is also defaults for the REST scheme:
# users_controller.rb
module MyProject
class UsersController < MyProject::Controller
# GET /
def index
view # `index` view by default
end
# GET /new
def new
view # `new` view by default
end
# POST /
def create
Model.create(model_params)
redirect :index
end
# GET /:id
def show(id)
@model = Model.first(id)
view # `show` view by default
end
# GET /edit/:id
def edit(id)
@model = Model.first(id)
view # `show` view by default
end
# PUT /:id
def update(id)
@model = Model.first(id)
if @model.update(model_params)
redirect :show, id: id
else
view :show, error: @model.errors
end
end
# PATCH /:id
def patch(id)
# the same, as update, but partially
end
# DELETE /:id
def delete(id)
@model = Model.first(id)
@model.destroy
redirect :index
end
private
def model_params
params[:model]
end
end
end
For others HTTP methods or action-paths you can specify it in the controller:
# foo_controller.rb
module MyProject
class FooController < Flame::Controller
get '/hello', def hello_world
'Hello, world!'
end
def my_name(name, last_name = nil)
"My name is #{name} #{last_name}"
end
post def bye
'Bye!'
end
end
end
or in a block while mounting:
mount ParentController do
get '/hello', :hello_world
## `get` - HTTP-method
## '/hello' - new URL-path
## :hello_world - controller's method name
post :bye
## `post` - HTTP-method
## URL-path as method-name by default
## :bye - controller's method name
## if you don't refine all public-method of controller (as `:my_name` for now)
## remain actions will be mount automatically
## (REST-matching, or with GET HTTP-method and path as method-name)
# You can mount nested controllers
mount NestedController, '/some_nested' # path will be '/parent/some_nested'
end
But don't forget about arguments while refining path!
# controller.rb
def hello(first_name, last_name = nil)
end
# application.rb
## default path => '/hello/:first_name/:?last_name'
## :first_name - required argument
## :?last_name - not required
get '/hello_world/:first_name/:?last_name', :hello
Since version 5
you don't have to mount all controllers manually: there is a support of automatic nested mounting.
For example, if you have MyProject::Site::Controller
(base, without actions, but with specific hooks and plugins),
MyProject::Site::IndexController
and a lot of MyProject::Site::FooController
—
they all will be mounted by:
# application.rb
mount :site
And if you have a parallel namespace with controllers, for example MyProject::API::Controller
,
just add mount :api
, that's all.
But don't forget to require them, there is Flame::Application.require_dirs
for such things.