我第一次使用Rails 3,并创建一个表单,其中每一行代表一个新的记录实例,一个动作按钮可以同时创建多个记录。我一直在关注 Rails 3 Edit Multiple Records in a Single Form 一般来说,一切似乎都运作良好。但是,仔细检查params []数组后,我注意到有些值是意外的。例如,如果复选框设置在窗体的某一行上,则在params []数组中,它位于窗体的错误行中。此外,params数组中似乎还有一个记录比实际应该创建的记录多一个。更具体地说
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
视图: testapp /应用/视图/观测/ 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 %>
控制器
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
路线:
match 'observations/update_observations'
match 'observations/editlist'
resources :observations
Gemfile
source 'http://rubygems.org'
gem 'rails', '3.0.0'
gem 'sqlite3-ruby', :require => 'sqlite3'
如果我然后创建两个新的观察,称为first(good = true)和second(good = false),这里是来自rails服务器输出的params值
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
从params []可以看出,虽然我选择第一条记录而不是第二条记录为true,但第一条记录为false,第二条记录为true。此外,还有第三条记录,其中good =&gt;是的,即使我只要求两条记录(或者我认为是这样!)
我最初的问题是复杂的形式,所以这是我尝试在一个简单的例子中重建它。非常感谢,wa
注意: 我刚刚用两个字符串字段重做了这个例子:即 schema.rb
create_table "observations", :force => true do |t|
t.string "name"
t.string "good"
t.datetime "created_at"
t.datetime "updated_at"
end
表单参数
没有问题Started 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
所以也许这与复选框有关?
(顺便说一句,通常使用布尔字段并使用复选框没有问题,使用生成的脚手架可以正常工作。当我将多个记录的表单的html与复选框进行比较时,以及单个表单的形式使用复选框(来自脚手架生成器)记录它们看起来是相同的。)