[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
실제로 제로 인덱스입니다 Hash
와 String
키, 아닌가 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_one
및 has_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
연관 문서 를 읽어보십시오 .