레일은 세 가지 모델과 네임 스페이스로 형성됩니다
-
07-07-2019 - |
문제
오랫동안 이것에 대해 내 머리를 두드렸다. 레일 2.3.2, 루비 1.9.1.
하나의 형식을 사용하여 이러한 관계가있는 세 가지 객체를 만들려고합니다.
class Person
has_one :goat
end
class Goat
belongs_to :person
has_many :kids
end
class Goat::Kid
belongs_to :goat
end
스키마의 요약은 다음과 같습니다.
Person
first_name
last_name
Goat
name
color
Goat::Kid
nickname
age
나는 나의 것을 원한다 #create
세 가지 모델의 새로운 인스턴스를 지정된 연관성으로 인스턴스화하기위한 조치. 그러나 내 Params Hash가 컨트롤러로 전달되는 것으로 보이지만 Goat::Kid
객체는 매개 변수를 수집하지 않습니다.
IRB (IRB 세션 #save!
또는 다른 필수품은 실제로 정확하지 않습니다. 브라우저/웹 양식을 통해이 작업을 수행하려고합니다.)
a = Person.new :first_name => 'Leopold', :last_name => 'Bloom'
b = Goat.new :name => 'Billy', :color => 'white'
c = Goat::Kid.new :nickname => 'Jr.', :age => 2
a.goat.kids
>> []
이제 파라를 각 객체에 전달하고 컨트롤러가 DB에 저장하도록하는 방법을 알 수 없습니다.
내 질문 : a) 사용하기에 좋은 곳입니다. nested_attributes_for
그렇다면 네임 스페이스로 어떻게 선언합니까? b)이 작업을 수행하는 방법을 이해하기가 훨씬 간단하고 쉽게 이해합니까?
매개 변수를 세 가지 모델로 전달하는 것은 나에게 매우 도전적이었습니다. 얼마나 많은 문서를 읽었더라도 머리를 감싸지 못합니다.#form_for
그리고 #fields_for
). 네임 스페이스는 이것을 더 복잡하게 만듭니다. 도움을 주셔서 감사합니다!
부록 : 결국 선언하면
accepts_nested_attributes_for
네임 스펙트 한 모델에 기호 인수를 사용하는 올바른 방법은 무엇입니까?
accepts_nested_attributes_for :kids, :through => :goats
또는
accepts_nested_attributes_for :goats_kids, :through => :goats
또는
accepts_nested_attributes_for :goats::kids, :through => :goats
네임 스케이터 모델이 어떻게 기호 식별자로 변환되는지 잘 모르겠습니다. 감사!
해결책
글쎄, 이번이 처음으로 놀았습니다 accepts_nested_attributes_for
, 그러나 약간의 연주로 나는 일할 무언가를 얻을 수있었습니다.
먼저 모델 설정 :
class Person < ActiveRecord::Base
has_one :goat
accepts_nested_attributes_for :goat
end
class Goat < ActiveRecord::Base
belongs_to :person
has_many :kids
accepts_nested_attributes_for :kids
end
class Goat::Kid < ActiveRecord::Base
belongs_to :goat
end
간단한 편안한 컨트롤러 :
ActionController::Routing::Routes.draw do |map|
map.resources :farm
end
class FarmController < ApplicationController
def new
end
def create
person = Person.new params[:person]
person.save
render :text => person.inspect
end
end
그런 다음 반 복잡한 형태가 나옵니다.
다음으로 양식 설정 :
<% form_for :person, :url => farm_index_path do |p| %>
<%= p.label :first_name %>: <%= p.text_field :first_name %><br />
<%= p.label :last_name %>: <%= p.text_field :last_name %><br />
<% p.fields_for :goat_attributes do |g| %>
<%= g.label :name %>: <%= g.text_field :name %><br />
<%= g.label :color %>: <%= g.text_field :color %><br />
<% g.fields_for 'kids_attributes[]', Goat::Kid.new do |k| %>
<%= k.label :nickname %>: <%= k.text_field :nickname %><br />
<%= k.label :age %>: <%= k.text_field :age %><br />
<% end %>
<% end %>
<%= p.submit %>
<% end %>
소스를 보면서 accepts_nested_attributes_for
, 그것은 당신이 호출하는 방법을 만들 것 같습니다. #{attr_name}_attributes=
, 그래서 나는 내 설정이 필요했습니다 fields_for
그것을 반영하기 위해 (레일 2.3.3). 다음으로, has_many :kids
작업 accepts_nested_attributes_for
. 그만큼 kids_attributes=
메소드는 객체의 배열을 찾고 있었으므로 배열 연관성을 수동으로 지정하고 fields_for
사용할 모델 유형.
도움이 되었기를 바랍니다.