northdig
northdig

Reputation: 479

Saving multiple records with params.require in ruby

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

Answers (5)

Tirlipirli
Tirlipirli

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

northdig
northdig

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

Vijay Chouhan
Vijay Chouhan

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

Vijayanand Nandam
Vijayanand Nandam

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

AndyV
AndyV

Reputation: 3741

Try this...

params.require(:service).permit( id: [ :client_id, :client_secret ] )

Upvotes: 0

Related Questions