[ruby-on-rails] has_many : through를 사용하는 Rails 중첩 양식, 조인 모델의 속성을 편집하는 방법은 무엇입니까?

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

그래서 토픽 컨트롤러의 “new”액션으로 글을 작성할 때 …

@topic.articles.build

… 토픽 /new.html.erb에 중첩 된 양식을 만듭니다 …

<% form_for(@topic) do |topic_form| %>
  ...fields...
  <% topic_form.fields_for :articles do |article_form| %>
    ...fields...

… Rails는 자동으로 링커를 생성합니다.
이제 내 질문에 대해 : 내 링커 모델에는 “새 주제”양식을 통해 변경할 수있는 속성도 있습니다. 그러나 Rails가 자동으로 생성하는 링커는 topic_id 및 article_id를 제외한 모든 속성에 대해 nil 값을 갖습니다. 다른 링커 속성에 대한 필드를 “new topic”양식에 넣어서 nil이 나오지 않게하려면 어떻게해야합니까?



답변

답을 찾았습니다. 트릭은 다음과 같습니다.

@topic.linkers.build.build_article

그러면 링커가 빌드 된 다음 각 링커에 대한 아티클이 빌드됩니다. 그래서, 모델 :
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...


답변

레일에 의해 생성 된 양식이 레일에 제출 될 때 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."
        }
      }
    }
  }
}

공지 사항에서는 linkers_attributes실제로 제로 인덱스입니다 HashString키, 아닌가 Array? 이는 서버로 전송되는 양식 필드 키가 다음과 같기 때문입니다.

topic[name]
topic[linkers_attributes][0][is_active]
topic[linkers_attributes][0][article_attributes][title]

레코드 생성은 이제 다음과 같이 간단합니다.

TopicController < ApplicationController
  def create
    @topic = Topic.create!(params[:topic])
  end
end


답변

솔루션에서 has_one을 사용할 때 빠른 GOTCHA. 난 그냥 사용자에 의해 주어진 답 붙여 복사합니다 KandadaBoggu 에서 이 스레드를 .


build메소드 서명은 다릅니다 has_onehas_many협회.

class User < ActiveRecord::Base
  has_one :profile
  has_many :messages
end

연결을위한 빌드 구문 has_many:

user.messages.build

연결을위한 빌드 구문 has_one:

user.build_profile  # this will work

user.profile.build  # this will throw error

자세한 내용 은 has_one연관 문서 를 읽어보십시오 .


답변