Trilhos formulário com três modelos e namespace
-
07-07-2019 - |
Pergunta
bater minha cabeça contra isso por um longo tempo. On Rails 2.3.2, Ruby 1.9.1.
Tentando usar um formulário para criar três objetos que têm essas relações:
class Person
has_one :goat
end
class Goat
belongs_to :person
has_many :kids
end
class Goat::Kid
belongs_to :goat
end
Aqui está um resumo do esquema:
Person
first_name
last_name
Goat
name
color
Goat::Kid
nickname
age
Eu gostaria de minha ação #create
instanciar novas instâncias de todos os três modelos com as associações especificadas. No entanto, embora pareça que a minha params de hash está sendo passado para o controlador como deveria (com base nos registros backtrace no navegador quando sopra para cima), o objeto Goat::Kid
não está coletando os parâmetros.
IRB (IRB sessão é apenas uma pseudo-representação do que eu estou tentando fazer isso, se ele não chama #save!
ou quaisquer outras necessidades que não é realmente significou para ser correto. Eu estou tentando fazer isso durante todo a forma navegador / web).
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
>> []
Agora, eu não posso descobrir como para obter a vista para passar os parâmetros para cada objeto e para obter o controlador para salvar esses parâmetros para o DB.
As minhas questões: a) é este um bom lugar para uso nested_attributes_for
e se assim como faço para declarar que, com um namespace? B) há um muito mais simples, mais fácil de entender maneira de fazer isso?
Passando parâmetros para três modelos acaba de ser muito desafiador para mim e não importa o quanto a documentação que eu li eu não posso envolver minha cabeça em torno dele (#form_for
e #fields_for
). O namespace complexifica ainda mais este. Obrigado por qualquer ajuda!
Adenda: se eu acabar declarando
accepts_nested_attributes_for
qual é a maneira correta de usar o argumento de símbolo para um modelo namespaced?
accepts_nested_attributes_for :kids, :through => :goats
ou
accepts_nested_attributes_for :goats_kids, :through => :goats
ou
accepts_nested_attributes_for :goats::kids, :through => :goats
Eu não tenho certeza de como modelos namespaced traduzir para seus identificadores de símbolos. Obrigado!
Solução
Bem, este é o meu primeiro tempo de jogo com accepts_nested_attributes_for
, mas com um pouco de jogo ao redor eu era capaz de conseguir algo para o trabalho.
Primeiro, a configuração do modelo:
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
Com um controlador repousante simples:
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
Em seguida, vem a forma semi-complexo:
A seguir, a configuração do formulário:
<% 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 %>
De olhar para a fonte para accepts_nested_attributes_for
, parece que ele irá criar um método para você chamado #{attr_name}_attributes=
, então eu precisava para configurar meu fields_for
para refletir que (Rails 2.3.3). Em seguida, recebendo o has_many :kids
trabalhar com accepts_nested_attributes_for
. O método kids_attributes=
estava à procura de um array de objetos, então eu precisava para especificar a associação matriz no formulário manualmente e dizer fields_for
que tipo de modelo a ser usado.
Espero que isso ajude.