Rails 4, strong parameters, nested resources, buil

2019-04-14 16:33发布

问题:

I am unable to get rails 4, strong parameters to work with nested resources via build. Any suggestions would be very welcome.

RSPEC shows me

Creating Actions Creating an action Failure/Error: click_button "Create Action" NoMethodError: undefined method permit' for "create":String # ./app/controllers/actions_controller.rb:24:inaction_params' # ./app/controllers/actions_controller.rb:10:in create' # ./spec/features/creating_actions_spec.rb:16:inblock (2 levels) in '

My Browser shows me:

NoMethodError in ActionsController#create undefined method `permit' for "create":String

Extracted source (around line #24):

def action_params params.require(:action).permit(:title, :description) end

Actions Controller contains:

def create
    @action = @project.actions.build(action_params)
    if @action.save
        flash[:notice] = "Action has been created."
        redirect_to [@project, @action]
    else
        flash[:alert] = "Action has not been created."
        render "new"
    end
end
private

def action_params
  params.require(:action).permit(:title, :description)
end

I am using nested resources:

resources :projects do
  resources :actions
end

The form is as following:

<%= form_for [@project, @action] do |f| %>
<% if @action.errors.any? %>
<div id="error_explanation" >
  <h2><%= pluralize(@action.errors.count, "error") %>
  prohibited this action from being saved:</h2>

  <ul>
  <% @action.errors.full_messages.each do |msg| %>
    <li><%= msg %></li>
  <% end %>
</ul>
 </div>
  <% end %>

 <p>
   <%= f.label :title %><br>
   <%= f.text_field :title %>
  </p>

  <p>
   <%= f.label :description %><br>
   <%= f.text_area :description %>
 </p>
 <%= f.submit %>
 <% end %>

回答1:

This is happening because Rails by default send a :action param containing the action that was requested. When you do params.require(:action) you're actually returning the name of the action requested as a string, in this case, create. You can explicitly tell form_for to use another key for the hash, solving your strong parameter problem:

<%= form_for [@project, @action], as: :foo do |f| %>

And in your controller:

params.require(:foo).permit...