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


103

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이 나오지 않게하려면 어떻게해야합니까?


3
나는 당신과 똑같은 일을하려고 노력하고 있습니다. 새로운 / 만들기 동작에서만 ... 당신이 당신의 컨트롤러 동작을 공유 할 수 있는지 궁금합니다. 나는를 만들 User을 통해 Account사용 a RelationshipA와 linker...하지만 나는 새와이 조치가 같은 ... 당신이 될까요 모습에 의미 만들 알아낼 수없는 이유는 무엇입니까?
Mohamad

답변:


90

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

@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...

13
이 도움이 있다면 알려주세요
Arcolye

13
Rails 3 업데이트 : Rails 3을 사용하는 경우 form_for 및 field_for에는 <% %> 대신 <% = %>가 필요합니다.
Arcolye

추가 한 두 개의 accepts_nested_attributes_for 줄 주위에 코드 백틱을 추가합니다. 코드를 스캔하는 동안 반복해서 그 정보를 놓쳤습니다. 자세히 읽어 보면 누락 된 세부 정보를 포착하여 문제를 해결했습니다. 감사!
TJ Schuck 2011 년

2
솔직히 이것은 rubyonrails.org 가이드에 필요한 완전한 예입니다.
ahnbizcad

시각적 선명도는 정말 먼 길을 가고 있습니다, TJ Schuck.
ahnbizcad

6

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

잘 모르겠습니다 만, 그것은 모두 함께 가정되었다고 생각합니다accepts_nested_attributes_for
Arcolye

2
@Arcolye-인터넷에서 이와 같은 협회에 대한 정보를 찾는 것은 그 당시에는 정말 고통 스러웠습니다. 나는 동료로서 적어도 여기에 문서화하고 싶었고 레일이 0 인덱스 해시 대신 linked_attributes를 배열로 변환했다고 가정했습니다. 바라건대이
간식

3

솔루션에서 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연관 문서 를 읽어보십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.