ControllerResources

Build Status Code Climate Test Coverage

A Rails engine providing a common DSL for fetching model resources in the controller and view layers. It leverages DecentExposure,StrongParameters and assumes an [ActiveRecord][ar]-like DSL for querying model objects. ControllerResources does not assume any part of your stack, instead providing generic tools and extensions to ActionController which allow you to use the fetched resources however you want.

resource :post do
  search :title, :category
  modify :title, :category, :body, :is_published
end

...and not have to worry about where the posts and post methods come from. If you're used to working with DecentExposure, you'll know that we're just using the expose macro to set up these resources, and using the resource macro to populate what we expose and additionally what parameters to pass through.

You can establish DecentExposure configuration with the resource block by calling methods which do not exist on the Resource. All of these methods are passed down to DecentExposure:

expose :post, param: :post_id
resource :comment do
  ancestor :post
  search :body
  modify :body, :user_id
end

Installation

Add this line to your application's Gemfile:

gem 'controller_resources'

Then run the following generator to generate the locale files for Responders:

$ rails generate responders:install

This will also insert Responders into your ApplicationController. If you do not want this, be sure to include the following code in a base controller somewhere...this is the best way for ControllerResources to function:

class ApplicationController < ActionController::Base
  responders :flash, :http_cache
end

Usage

Define your resource in the controller, and you can use methods instead of instance variables to access the model object. No more writing finder methods!

class ItemsController < ApplicationController
  resource :item do
    search :name, :user
    modify :name, :user, :is_private
  end

  def index
    respond_with items
  end

  def show
    respond_with item
  end

  def create
    item.save
    respond_with item
  end
end

In your view, you can use methods instead of instance variables to access the model objects passed down into the template:

<%= user.name %>

<<<<<<< HEAD You can also use some given helpers for establishing authorization logic in ApplicationController. Since ControllerResources is included by default, you can use the given current_resource method to tell Pundit (for example) which policy to use in authorization:

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  before_action :authorize_user!

  rescue_from Pundit::NotAuthorizedError, with: :forbidden

  def forbidden
    render 'forbidden', status: :forbidden
  end

  private

  def authorize_user!
    authorize current_user, current_resource, current_action
  end

  def current_action
    :"#{action_name}?"
  end
end

This current_resource method is populated by the given configured Resource object, which will attempt to classify its model_name and provide a class constant that can be used here. In the PostsController#show action, for example, that call to authorize would be partially expanded like this:

authorize current_user, Post, :show?

(where current_user is the authenticated User found by Devise)

While ControllerResources doesn't provide authorization or authentication helpers, it does provide the necessary methods to aid your own authorization and authentication frameworks in their job.

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.

To run tests:

$ rake test

This will also use Rubocop to lint-check your code so it adheres to our style guide.