Integration with strong_parameters #236

Closed
dpmccabe opened this Issue Aug 28, 2012 · 14 comments

Comments

Projects
None yet
9 participants

Has anyone figured out a way to integrate Inherited Resources with the Strong Parameters gem, which might be making its way into Rails 4? Sure, you could overwrite the create and update actions on all of your controllers, but that would defeat the purpose of using Inherited Resources at all.

khelben commented Sep 21, 2012

You need to overwrite the #resource_params method in your controller.

One gotcha though, you'll need to wrap the result in an array like this:
Second gotcha, IR also calls this method on get #new where the params most off the time is empty and would raise an ParamsRequiredError.

def resource_params
    return [] if request.get?
    [ params.require(:employee).permit(:name, :age) ]
end

edit: update example, thx to @btucker
edit2: thx @anlek for reminding me of the get #new issue

btucker commented Oct 2, 2012

@khelben I believe the method name in your example above should be resource_params.

khelben commented Oct 3, 2012

@btucker thx for spotting, updated the example

anlek commented Oct 18, 2012

This seems to raise a Required parameter missing: page on the new action when I have this set:

  def resource_params
    [ params.require(:page).permit(:title, :permalink, :content) ]
  end

khelben commented Oct 18, 2012

That means that your params hash is missing the required ':page' key.

anlek commented Oct 19, 2012

Understood, but the 'new' action doesn't require the params hash at all. (unless it fail validation)

khelben commented Oct 19, 2012

You're right. You've hit something I've encountered myself.

The thing is: inherited resources also calls #resource_params on a new action, where most of the times the params is empty.

I've updated the example with some more explanation

Hi, I've been trying to use inherited resources with the strong_parameters gem as seen here.
It almost works, the only problem is that when the parameters reach the sanitize_for_mass_assignmentmethod from ActiveModel::ForbiddenAttributesProtection it is converted from ActionController::Parameters to Hash, so the method ignores it because it doesn't respond to the method permit. This causes that it allows mass assignment for unpermitted attributes if they are passed as a Hash instead an ActionController::Parameters. Is anyone having the same issue?

EDIT: Nevermind, it was a problem with mongoid and how it passes multiparameter attributes to the method. I've already fixed it.

Hey guys,

This is actually really easy. Not sure why everyone is having so much trouble with it. Just drop this into an intitializer

inherited_resources_strong_parameters.rb

# Add Strong Attributes suuport to all models (Remove in Rails4)
ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)

# MonkeyPatch Inherited Resources to support strong parameters
module InheritedResources
  module BaseHelpers
    protected

      def build_resource
        get_resource_ivar || set_resource_ivar(end_of_association_chain.send(method_for_build, request.get ? {} : resource_params))
      end

      def update_resource(object, attributes)
        object.update_attributes(attributes)
      end

  end
end

Now just define your params as you would for strong_attributes using resource_params

def resource_params
  params.require(:group).permit(:name, :description)
end

The main issue is that inherited_resources was splatting the attirbutes to support stuff like {params}, {:role => 'admin'}
Since roles have been removed in Rails4, we just need to remove the splat from the build and update methods and it works fine. We also skip the params for get requests since build_resource runs for new as well.

Contributor

joelmoss commented Dec 24, 2012

Even better, please fork and submit a pull request with these changes (along with tests) and we can release it as part of the next IR release.

joelmoss closed this Dec 24, 2012

Sure. Just wanted to provide and interim solution for those who were asking. I can make a pull request with tests for Rails 4 as long as it doesn't need to be backwards compatible.

Contributor

joelmoss commented Dec 24, 2012

Yes it should be backwards compatible for those wanting to use it with Rails 3 and the Strong Params gem

Joel Moss

Develop with Style at http://DevelopWithStyle.com

Call me +44 7791 503309
http://twitter.com/joelmoss
AIM: joelkmoss
Skype: joelmoss.info

On Monday, 24 December 2012 at 16:15, aaronchi wrote:

Sure. Just wanted to provide and interim solution for those who were asking. I can make a pull request with tests for Rails 4 as long as it doesn't need to be backwards compatible.


Reply to this email directly or view it on GitHub (josevalim#236 (comment)).

emilford commented Jan 8, 2013

@aaronchi,

I was getting the error "undefined method get" and had to change request.get to request.get? in the build_resource method.

I am also still working on getting the permitted parameters working. Currently updates aren't being made on the resource, despite the attribute being in the list. This works. The problem was in my code.

Contributor

taavo commented Feb 26, 2013

Note that @aaronchi's patch above only works if you're using params.require. This patch may be more versatile:

module InheritedResources
  module BaseHelpers
    protected
      def resource_params
        parameters = respond_to?(:permitted_params) ? permitted_params : params
        rparams = [parameters[resource_request_name] || parameters[resource_instance_name] || {}]
        rparams << as_role if role_given?
        rparams
      end
  end
end

Then set what parameters are permitted in the controller, in a method named permitted_params:

def permitted_params
  params.permit(:other_parameter, :group => [:name, :description])
end

(It seems like a strong_parameters api problem that permit stays at the top of the params hash, but require drills down a level, leaving no way to require one parameter but not the other. Maybe they'll sort that out eventually.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment