Editing Multiple Records on a single form example has unexpected params values
I am using Rails 3 for the first time, and making a form where each row represents a new instance of a record, with one action button to create the multiple records all at once. I have been following Rails 3 Edit Multiple Records in a Single Form and in general it all seems to work well. However, on closer examination of the params[] array, I noticed that some of the values are unexpected. For example, if the checkbox is set on one of the lines of the form, in the params[] array it is in the wrong line of the form. Also, there appears to be one more record in the params array than was actually supposed to have been created. More specifically
rails --version
Rails 3.0.0
ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux]
database schema:
create_table "observations", :force => true do |t|
t.string "name"
t.boolean "good"
t.datetime "created_at"
t.datetime "updated_at"
end
view: testapp/app/views/observations/editlist.html.erb
<% form_tag :action => 'update_observations', :method => :put do %>
<table>
<% for observation in @observations %>
<%= fields_for 'observations[]', observation do |f| %>
<tr>
<td>
<%= f.label :name %>
<%= f.text_field :name %></td>
<td>
<%= f.label :good %>
<%= f.check_box :good %> </td>
</tr>
<% end %>
<% end %>
</table>
<p><%= submit_tag "Submit" %></p>
<% end %>
Controller
def editlist
@num = 2
@observations = Array(@num)
(0..@num-1).each do |index|
@observations[index] = Observation.new
end
respond_to do |format|
format.html
format.xml { head :ok }
end
end
def update_observations
@observations = params[:observations].collect { |observation| Observation.new(observation) }
@observations.each do |obs|
obs.save
end
redirect_to :action => 'index'
end
routes:
match 'observations/update_observations'
match 'observations/editlist'
resources :observations
Gemfile
source 'http://rubygems.org'
gem 'rails', '3.0.0'
gem 'sqlite3-ruby', :require => 'sqlite3'
If I then create two new observations called first (good=true) and second (good=false), here is the params value from the rails server output
Started POST "/observations/update_observations?method=put" for 127.0.0.1 at 2011-01-17 12:26:55 +1030
Processing by ObservationsController#update_observations as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"CnTHEE7L1tPndgmNZF2KEGddU/WlDf6jl8SAEiwCz6Q=", "observations"=>[{"name"=>"first", "good"=>"0"}, {"good"=>"1", "name"=>"second"}, {"good"=>"0"}], "commit"=>"Submit", "method"=>"put"}
SQL (0.3ms) SELECT name
FROM sqlite_master
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
SQL (0.4ms) INSERT INTO "observations" ("created_at", "good", "name", "updated_at") VALUES ('2011-01-17 01:56:55.262688', 'f', 'first', '2011-01-17 01:56:55.262688')
SQL (0.4ms) INSERT INTO "observations" ("created_at", "good", "name", "updated_at") VALUES ('2011-01-17 01:56:55.347775', 't', 'second', '2011-01-17 01:56:55.347775')
SQL (0.4ms) INSERT INTO "observations" ("created_at", "good", "name", "updated_at") VALUES ('2011-01-17 01:56:55.458927', 'f', NULL, '2011-01-17 01:56:55.458927')
Redirected to http://localhost:3000/observations
Completed 302 Found in 264ms
As you can see from the params[], although I select good to be true for the first record and not the second record, it is false for the first record, and true for the second record. And further, there is a third record with good => false, even if I only asked for two records (or so I think!)
My original problem was with a complex form, so this is my attempt at reconstructing it in a simple example. Thank you very much, wa
NOTE: I have just redone the example with two string fields: i.e. schema.rb
create_table "observations", :force => true do |t|
t.string "name"
t.string "good"
t.datetime "created_at"
t.datetime "updated_at"
end
And there is no problem with the form parameters
开发者_StackOverflowStarted POST "/observations/update_observations?method=put" for 127.0.0.1 at 2011-01-17 13:21:24 +1030
Processing by ObservationsController#update_observations as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"CnTHEE7L1tPndgmNZF2KEGddU/WlDf6jl8SAEiwCz6Q=", "observations"=>[{"name"=>"six", "good"=>"6"}, {"name"=>"seven", "good"=>"7"}], "commit"=>"Submit", "method"=>"put"}
SQL (0.3ms) SELECT name
FROM sqlite_master
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
SQL (0.5ms) INSERT INTO "observations" ("created_at", "good", "name", "updated_at") VALUES ('2011-01-17 02:51:24.248045', '6', 'six', '2011-01-17 02:51:24.248045')
SQL (0.3ms) INSERT INTO "observations" ("created_at", "good", "name", "updated_at") VALUES ('2011-01-17 02:51:24.318928', '7', 'seven', '2011-01-17 02:51:24.318928')
Redirected to http://localhost:3000/observations
So maybe it is something to do with checkboxes?
(By the way, there is no problem ordinarily with the boolean field and using checkboxes, it works fine using the scaffold generated. When I compare the html for the form for multiple records with the checkbox, and the form for the single record with the checkbox ( from the scaffold generator) they appear to be identical.)
精彩评论