我知道这里有几个不同的帖子,人们试图让他们的Rails 3表格与嵌套模型一起工作。"#34;我看了很多,包括Subclass Isn't Saving和Nested Model with Polymorphic Association,还有看Ryan Bates'关于Nested Model Forms的Railscasts和他关于复杂表格的两个教程。
那就是说,我很难理解为什么我的表格中的对象不能保存。
以下是我的模特:
course.rb
class Course < ActiveRecord::Base
attr_accessible :course_name, :course_semester, :course_summary, :course_year, :objectives_attributes
has_many :objectives, as: :objectiveable
accepts_nested_attributes_for :objectives, :reject_if => lambda { |a| a[:objective].blank? }, :allow_destroy => true
objective.rb
class Objective < ActiveRecord::Base
attr_accessible :objective
belongs_to :objectiveable, polymorphic: true
我的表格:
new.html.erb
<%= form_for [current_user, @course] do |course| %>
<%= course.label "Course Name" %>
<%= course.text_field :course_name, id:"course_name" %>
<%= course.label "Semester" %>
<%= course.select(:course_semester,[['Fall', 'Fall'], ['Spring', 'Spring'], ['Summer', 'Summer'], ['Winter','Winter']] ) %>
<%= course.label "Course Year" %>
<%= course.text_field :course_year, id:"course_year" %>
<p>Course Objectives</p>
<%= course.fields_for :objectives do |objective| %>
<%= objective.text_field :objective, name: "objective" %>
<% end %>
<%= course.label "Course Summary" %>
<%= course.text_area :course_summary, id:"course_summary" %>
<%= course.submit "Save and Return", name: "save_and_return" %>
<%= course.submit "Create a Unit", name: "course_to_unit" %>
<% end %>
我的控制器:
courses_controller.rb
class CoursesController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
def new
@course = current_user.courses.new
@course.objectives.build
end
def create
@course = current_user.courses.new(params[:course])
if @course.save && params[:save_and_return]
redirect_to user_path(current_user)
elsif @course.save && params[:course_to_unit]
redirect_to new_course_unit_path(@course)
else
flash[:notice] = "Sorry, there was a mistake with the form"
render 'new'
end
end
我的日志:
test.log中
Started POST "/users/1/courses" for 127.0.0.1 at 2012-11-27 22:23:00 -0500
Processing by CoursesController#create as HTML
Parameters: {"utf8"=>"✓", "course"=>{"course_name"=>"Physics 1", "course_semester"=>"Fall", "course_year"=>"2012", "course_summary"=>"This is a valid course summary."}, "objective"=>"An objective", "save_and_return"=>"Save and Return", "user_id"=>"1"}
[1m[36mUser Load (0.2ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1[0m
[1m[35m (0.0ms)[0m begin transaction
[1m[36mSQL (0.7ms)[0m [1mINSERT INTO "courses" ("course_name", "course_semester", "course_summary", "course_year", "created_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?)[0m [["course_name", "Physics 1"], ["course_semester", "Fall"], ["course_summary", "This is a valid course summary."], ["course_year", 2012], ["created_at", Wed, 28 Nov 2012 03:23:00 UTC +00:00], ["updated_at", Wed, 28 Nov 2012 03:23:00 UTC +00:00], ["user_id", 1]]
[1m[35m (6.1ms)[0m commit transaction
Redirected to http://www.example.com/users/1
Completed 302 Found in 17ms (ActiveRecord: 7.0ms)
我可以在日志中看到参数哈希中的目标,但是在提交数据时没有在Objective表中插入任何内容。在我的控制台中,我能够使用@ course.objectives.create或@ course.objectives.build创建目标,所以我知道关联正在起作用(加上我在Rspec中测试了模型)。但我无法在表格层面弄清楚我在做错了什么。
我还应该注意到我在Rspec中运行它作为测试,看起来像这样:
courses_pages_spec.rb
it "Adds at least one objective to the course" do
expect {
fill_out_course_form_with_valid_info
click_button save_button
}.to change(Course, :count).by_at_least(1)
Course.last.objectives.count.should == 1
end
虽然我也启动了Rails服务器,但在表单中输入值并获得相同的结果。
提前感谢您的帮助。
答案 0 :(得分:0)
所以,答案比我想象的要容易得多。在我的嵌套表格中,我有以下内容:
<p>Course Objectives</p>
<%= course.fields_for :objectives do |objective| %>
<%= objective.text_field :objective, name: "objective" %>
<% end %>
事实证明,通过将“name”定义为“objective”,我覆盖了默认的“name”,“course [goals_attributes] [0] [objective]”,这是参数传递的位置/方式。
根据Rails Docs,
与使用vanilla HTML相比,表单助手旨在使资源使用变得更加容易。
使用form_for创建模型的表单。该方法产生一个表单构建器,它知道表单所涉及的模型。因此,表单构建器可以为与模型属性对应的输入字段生成默认值,还可以生成方便的名称,ID,端点等。
生成的字段名称中的约定允许控制器接收在params中很好地构建的表单数据,而不需要您的努力。
我首先拥有“名字”属性的原因是为了让Capybara能够在我的测试中找到一些东西。猜猜这不是一个好主意: - )
(我所做的是使用Firebug来确定表单字段的ID是什么,然后对其进行测试。)