Rails 3.2从子视图创建父模型

时间:2012-01-20 00:01:44

标签: ruby-on-rails forms nested-forms belongs-to fields-for

我很难理解如何做到这一点。我有两个模型,一个项目和一个课程。

#project.rb
belongs_to :course
attr_accessible :course_id, :course
accepts_nested_attributes_for :course, reject_if: lambda { |a| a[:course_id] == 0 }

#course.rb
has_many :projects

Projects#new页面(子对象)上,我想输入新course的名称并让它创建父对象。

这是我在视图中的尝试,但它似乎没有正常工作。

= form_for [@user, @project] do |f|

  # Other fields

  = fields_for :course do |builder|
    = builder.label :name, 'Course Name'
    = builder.text_field :name

  = f.submit

我稍后会使用这个父对象来创建更多项目,但是现在,让我们假设它不存在。

更新1 我修改了我的fields_for(根据Ryan的要求):

= form_for [@user, @project] do |f|

  # Other fields

  = f.fields_for :course do |builder|
    = builder.label :name, 'Course Name'
    = builder.text_field :name

  = f.submit

我正在使用haml,因此=应该显示,但是字段甚至不显示在页面上或生成的html中。任何线索,为什么会这样? (提交按钮确实显示)

更新2 我找到了一个潜在的解决方案,但我不确定这是否是接近这个问题的正确方法。在控制器中,我需要为fields_for构建一个课程来显示。

# ProjectsController
def new
  @project  = @user.projects.new
  @project.build_course
end

# project.rb
attr_accessible :course_attributes
# So yes, I now see what you were talking about, regarding the course_attributes

2 个答案:

答案 0 :(得分:3)

您应该使用表单构建器来构建对象,而不仅仅是fields_for

你有这个:

= fields_for :course do |builder|

你应该在哪里:

= f.fields_for :course do |builder|

不同之处在于,通过在初始表单构建器上调用它,Rails将检查初始course_attributes=调用对象上是否存在form_for方法(在这种情况下,即' d为@project),如果有,则会将此表单中的字段定义为course_attributes

在此更改之前和之后继续检查表单,只是为了看看。我等一下。

这可以通过模型中的accepts_nested_attributes_for调用来实现。这个方法定义了允许嵌套属性工作的course_attributes=方法。一旦你创建了项目,它就应该创建课程。

此外,无需将course_id设为可访问属性,因为您的表单不会设置该属性。

答案 1 :(得分:0)

我使用了宝石'动态形态'。 教师名单(教师姓名)表包含院系名称。

<%= f.select :faculty, options_from_collection_for_select(@faculty_list, 'id', 'faculty_name', @faculty.faculty.to_i) %>