ControllerResources
A Rails engine providing a common DSL for fetching model resources in the controller and view layers.
Turn this:
class PostsController < ApplicationController
before_action :find_post, except: [:index]
respond_to :html
def index
@posts = Post.where(search_params)
respond_with @posts
end
def show
respond_with @post
end
private
def find_post
@post = Post.find params[:id]
end
end
Into this:
class PostsController < ApplicationController
resource :post
respond_to :html
def index
respond_with @posts
end
end
You can also specify an ancestor, which is used to look up the given resource.
In this example, @comment
is being looked up using
@post.comments.find
rather than the default Comment.find
:
class CommentsController < ApplicationController
before_action :find_post
resource :comment, ancestor: :post
def show
respond_with @comment
end
private
def find_post
@post = Post.find params[:post_id]
end
end
Installation
Add this line to your application's Gemfile:
gem 'controller_resources'
And run
$ bundle install
Then, include the module in your base controller class:
class ApplicationController < ActionController::Base
include ControllerResources
end
Usage
Using the resource
macro, you can define the name of your resource
which will be used to derive instance variable names and class names for
your models. ControllerResources assumes that your instance variables
are named conventionally, and assumes that you follow Rails best
practices when assigning instance variables in the controller.
class CommentsController < ApplicationController
before_action :find_post
resource :comment, ancestor: :post
respond_to :html
def show
respond_with @comment
end
def new
@comment = @post.comments.build
end
def create
authorize @comment
@comment = @post.comments.create permitted_params(Comment)
respond_with @comment
end
def update
authorize @comment
@comment.update permitted_params(Comment)
respond_with @comment
end
private
def find_post
@post = Post.find params[:post_id]
end
end
Meta-Programming Capabilities
Since ControllerResources
is programatically defining exposure methods
for you, it also keeps references to the name given in the resource
block so you can infer what kind of object you are using in your view.
The model_name
, collection_name
and model
/ collection
methods
are included as helpers along with the rest of the exposure methods in
your view as well as the controller.
For more, consult the RDoc Documentation
Customization
As said before, the model
and collection
methods are exposed for you
in the controller, and are what is used as the values for the instance
variables set in :find_resource
. You can override these methods in
your base controller class to perform authorization or decoration logic
in a consistent manner, like so:
class ApplicationController < ActionController::Base
include ControllerResources
include Makeover::Presentable
include Pundit
protect_from_forgery with: :exception
private
def model
present authorize(super)
end
def collection
present policy_scope(records)
end
end
Contributing
Contributions to ControllerResources
may be made using GitHub pull
requests. You must include accompanying tests, and all tests must pass
for any contribution to be considered.
NOTE: Running tests requires that you have PhantomJS installed.
To run tests:
$ bin/rake test
This will also use Rubocop to lint-check your code so it adheres to our style guide.
Releasing
All acceptance testing and final RubyGems.org releasing is performed automatically by Travis CI. When a new gem version needs to be released, one with push access to the repo can update the version by running the following Rake task, which will tag the latest version of the gem and push all commits to GitHub, where it will be picked up by Travis and auto-deployed to RubyGems:
$ bin/rake release
Compatibility
ControllerResources adheres to the Semantic Versioning standard for publishing new versions of the library. Bug fixes will be pushed in patch updates, while new features that maintain compatibility will be available in minor updates. Major updates are reserved for new features that break existing compatibility.
Ruby version support
This project will be tested against any version of MRI that is currently being supported by the Ruby core team. It is not currently being tested on JRuby or Rubinius. For more information on what versions of Ruby we're testing, see Travis CI.