Reputation: 479
I'm trying to update multiple records. The form generates fine and submits fine and the data is sent. The records are looked up to update, but no data is ever saved. I have my controller logic, form logic and console dump below. I'm trying to duplicate what Anthony Lewis put together but I have a feeling I am not passing the right data into or defining correctly the params.require().permit()
method. Thanks in advance for your help!
class ConfigController < ApplicationController
def edit
@services = Service.all
end
def update
params["service"].keys.each do |id|
@service = Service.find(id.to_i)
@service.update_attributes!(service_params)
end
redirect_to config_url
end
private
def service_params
params.require(:service).permit(:id, :client_id, :client_secret)
end
end
Form code is:
<%= form_for :service, :url => update_config_path, :html => { :class => "form-horizontal", :method => "put", :remote => true } do %>
<% @services.each do |s| %>
<%= fields_for "service[]", s do |service_field| %>
<fieldset>
<legend><%= s.name %></legend>
<div class="form-group">
<%= service_field.label :client_id, "Consumer Key", :class => "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= service_field.text_field :client_id, :class => "form-control" %>
</div>
</div>
<div class="form-group">
<%= service_field.label :client_secret, "Consumer Secret", :class => "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= service_field.text_field :client_secret, :class => "form-control" %>
</div>
</div>
</fieldset>
<% end %>
<% end %>
<%= submit_tag %>
<% end %>
Console reads:
Started PUT "/config" for 127.0.0.1 at 2013-11-22 15:44:08 -0800
Processing by ConfigController#update as JS
Parameters: {"utf8"=>"✓", "service"=>{"1"=>{"client_id"=>"testid", "client_secret"=>"testsecret"}, "2"=>{"client_id"=>"testkey", "client_secret"=>""}, "3"=>{"client_id"=>"", "client_secret"=>""}}, "commit"=>"Save changes"}
Service Load (0.3ms) SELECT "services".* FROM "services" WHERE "services"."id" = $1 LIMIT 1 [["id", 1]]
Unpermitted parameters: 1, 2, 3
(0.1ms) BEGIN
(0.1ms) COMMIT
Unpermitted parameters: 1, 2, 3
{}
Service Load (0.2ms) SELECT "services".* FROM "services" WHERE "services"."id" = $1 LIMIT 1 [["id", 2]]
Unpermitted parameters: 1, 2, 3
(0.1ms) BEGIN
(0.1ms) COMMIT
Unpermitted parameters: 1, 2, 3
{}
Service Load (0.2ms) SELECT "services".* FROM "services" WHERE "services"."id" = $1 LIMIT 1 [["id", 3]]
Unpermitted parameters: 1, 2, 3
(0.1ms) BEGIN
(0.1ms) COMMIT
Unpermitted parameters: 1, 2, 3
{}
Redirected to http://localhost:3000/config
Completed 302 Found in 6ms (ActiveRecord: 1.1ms)
Upvotes: 2
Views: 1151
Reputation: 113
Please try:
def update
Service.update(service_params.keys, service_params.values
end
def service_params
params.permit(service: [:client_id, :client_secret]).require(:service)
end
Upvotes: 0
Reputation: 479
I found a solution, but perhaps it isn't the best. Let me know if someone has a better idea and I'd be happy to try it!
In the solution I updated my controllers update
action and the service_params
.
I passed id
to service_params
and called fetch
method on the require
method to get the correct params. I noticed that in the console it read Unpermitted parameters: 1, 2, 3
when it was saving each record indicating the params were an array and I also noticed in @Vijay's solution he tried to narrow down the params as well. After some Googling and console logging I came up with the code below.
def update
params["service"].keys.each do |id|
@service = Service.find(id.to_i)
@service.update_attributes!(service_params(id))
end
redirect_to config_url
end
def service_params(id)
params.require(:service).fetch(id).permit( :client_id, :client_secret )
end
What do you think?
Upvotes: 3
Reputation: 4893
Try this one and it will work.
Let me know if you get any issue
def service_params
params.require(:service).map do |_, p|
p.permit(:id, :client_id, :client_secret)
end
end
http://blog.sensible.io/2013/08/17/strong-parameters-by-example.html
Upvotes: 0
Reputation: 882
Your strong parameters line should be
params.require(:service).permit( [:id, :client_id, :client_secret ] )
This permits arrays of values http://guides.rubyonrails.org/action_controller_overview.html#more-examples
Upvotes: 0
Reputation: 3741
Try this...
params.require(:service).permit( id: [ :client_id, :client_secret ] )
Upvotes: 0