Rails嵌套表单与has_many:through,如何编辑连接模型的属性?

Arc*_*lye 103 nested join ruby-on-rails nested-forms

使用accepts_nested_attributes_for时如何编辑连接模型的属性?

我有3个模型:由连接器加入的主题和文章

class Topic < ActiveRecord::Base
  has_many :linkers
  has_many :articles, :through => :linkers, :foreign_key => :article_id
  accepts_nested_attributes_for :articles
end
class Article < ActiveRecord::Base
  has_many :linkers
  has_many :topics, :through => :linkers, :foreign_key => :topic_id
end
class Linker < ActiveRecord::Base
  #this is the join model, has extra attributes like "relevance"
  belongs_to :topic
  belongs_to :article
end
Run Code Online (Sandbox Code Playgroud)

所以当我在主题控制器的"新"动作中构建文章时......

@topic.articles.build
Run Code Online (Sandbox Code Playgroud)

...并在topics/new.html.erb中创建嵌套表单...

<% form_for(@topic) do |topic_form| %>
  ...fields...
  <% topic_form.fields_for :articles do |article_form| %>
    ...fields...
Run Code Online (Sandbox Code Playgroud)

... Rails自动创建链接器,这很棒. 现在我的问题是:我的链接器模型还具有我希望能够通过"新主题"表单更改的属性.但是Rails自动创建的链接器除了topic_id和article_id之外,其所有属性都有nil值.如何将其他链接器属性的字段放入"新主题"表单中,这样它们就不会出现?

Arc*_*lye 90

想出答案.诀窍是:

@topic.linkers.build.build_article
Run Code Online (Sandbox Code Playgroud)

构建链接器,然后为每个链接器构建文章.因此,在模型中:
topic.rb需要accepts_nested_attributes_for :linkers
linker.rb需要accepts_nested_attributes_for :article

然后在表格中:

<%= form_for(@topic) do |topic_form| %>
  ...fields...
  <%= topic_form.fields_for :linkers do |linker_form| %>
    ...linker fields...
    <%= linker_form.fields_for :article do |article_form| %>
      ...article fields...
Run Code Online (Sandbox Code Playgroud)

  • 如果这有用,请告诉我 (13认同)
  • Rails 3更新:如果您使用的是Rails 3,则form_for和field_for需要<%=%>而不是<%%>. (13认同)
  • 老实说,这是rubyonrails.org指南需要的完整示例. (2认同)

Dan*_*ema 6

当Rails生成的表单提交给Rails时controller#action,params将具有与此类似的结构(添加了一些组成的属性):

params = {
  "topic" => {
    "name"                => "Ruby on Rails' Nested Attributes",
    "linkers_attributes"  => {
      "0" => {
        "is_active"           => false,
        "article_attributes"  => {
          "title"       => "Deeply Nested Attributes",
          "description" => "How Ruby on Rails implements nested attributes."
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意linkers_attributes,实际上如何Hash使用String键进行零索引,而不是Array?嗯,这是因为发送到服务器的表单字段键如下所示:

topic[name]
topic[linkers_attributes][0][is_active]
topic[linkers_attributes][0][article_attributes][title]
Run Code Online (Sandbox Code Playgroud)

创建记录现在很简单:

TopicController < ApplicationController
  def create
    @topic = Topic.create!(params[:topic])
  end
end
Run Code Online (Sandbox Code Playgroud)

  • @Arcolye - 在互联网上为这样一个协会找到这些信息当时是一种痛苦 - 也许我的谷歌当天不在了.我想至少在这里记录它作为我和我的同事,我只是假设rails将linked_attributes转换为数组,而不是零索引哈希.希望这个花絮可以帮助将来的人:) (2认同)