/action_parameter

ActionParameter helps you move all your parameter's logic from controllers into it's own class. This way you'll keep your controllers dry and they'll be easier to test.

Primary LanguageRubyMIT LicenseMIT

Gem Version Build Status Coverage Status Code Climate Bitdeli Badge

ActionParameter

ActionParameter helps you move all your parameter's logic into it's own class. This way you'll keep your controllers dry and they would be easier to test.

Before

# app/controllers/users_controllers.rb
class UsersController < ActionController::Base
  def create
    User.create(user_params)
  end

  private
    def user_params
      params.require(:user).permit(:name, :age)
    end
end

After

# app/controllers/users_controllers.rb
class UsersController < ActionController::Base
  def create
    # It automatically deduces which Parameters class from Controller's name
    User.create(permitted_params.permit)
  end
end
# app/parameters/user_parameters.rb
class UserParameters < ActionParameter::Base
  def permit
    params.require(:user).permit(:name, :age)
  end
end

Install

ActionParameter works with Rails 3.0 onwards and Ruby 1.9.3 onwards. You can add it to your Gemfile with:

gem 'action_parameter'

Run the bundle command to install it.

Usage

####Generator

rails generate parameters [MODEL_NAME]

Will create app/parameters/[model_name]_parameters.rb.

####Controller Helpers

  • permitted_params: Returns an ActionParameter instance.
permitted_params(options={})

#####Options Hash

  • options - Hash with one valid key: :class.
  • options[:class] - Symbol value with the name of the Parameters class you want to use.

#####Example 1

# app/controllers/people_controllers.rb
class PeopleController < ActionController::Base
  def create
    Person.create(permitted_params.permit) # This will call to PersonParameters' permit method
  end
end
# app/parameters/person_parameters.rb
class PersonParameters < ActionParameter::Base
  def permit
    params.require(:person).permit(:name, :age)
  end
end

#####Example 2

# app/controllers/people_controllers.rb
class PeopleController < ActionController::Base
  def create
    Person.create(permitted_params(class: :user).sign_up) # This will call to UserParameters' sign_up method
  end
end
# app/parameters/user_parameters.rb
class UserParameters < ActionParameter::Base
  def sign_up
    params.require(:person).permit(:name, :age)
  end
end

####Parameter Class Helpers

#####Default Helpers

  • params: Returns params from the current controller request which instantiated the Parameter class.
  • controller_name: Returns the controller's name from which the Parameter class was instantiated.
  • action_name: Returns the action's name from the controller from which the Parameter class was instantiated.

#####Creating New Helpers

If you want to create new helper methods for your parameters class, just call locals method over permitted_params. Let say you want to make @current_user available for the UserParameter's class under the user method, then you'll need to use the locals method to tell the UserParameters class to create a new helper that returns @current_user.

permitted_params(class: :user).locals( user:           @current_user,
                                       another_helper: @value )

This will create user and another_helper methods and they will be available in UserParameters class.

#####Example

# app/controllers/users_controllers.rb
class UsersController < ActionController::Base
  def create
    User.create(permitted_params.locals(user: @current_user).permit) # This will call to UserParameters' permit method
  end
end
# app/parameters/user_parameters.rb
class UserParameters < ActionParameter::Base
  def permit
    if user.admin?
        params.require(:person).permit(:name, :age, :admin)
    else
        params.require(:person).permit(:name, :age)
    end
  end
end

RSpec

This example shows how to test using RSpec.

Theses tests require your test.rb configured to config.action_controller.action_on_unpermitted_parameters = :raise.

# spec/parameters/user_parameters_spec.rb
require "spec_helper"

describe UserParameters do
  describe ".permit" do
    describe "when permitted parameters" do
      it "returns the cleaned parameters" do
        user_params = { first_name: "John", last_name: "Doe" }
        params = ActionController::Parameters.new(user: user_params)

        permitted_params = UserParameters.new(params).permit

        expect(permitted_params).to eq user_params.with_indifferent_access
      end
    end

    describe "when unpermitted parameters" do
      it "raises error" do
        user_params = { foo: "bar" }
        params = ActionController::Parameters.new(user: user_params)

        expect{ UserParameters.new(params).permit }.
          to raise_error(ActionController::UnpermittedParameters)
      end
    end
  end
end