Les rails forment trois modèles et un espace de noms
-
07-07-2019 - |
Question
me frapper la tête contre celui-ci pendant longtemps. Sur les rails 2.3.2, Ruby 1.9.1.
Essayer d'utiliser un formulaire pour créer trois objets ayant ces relations:
class Person
has_one :goat
end
class Goat
belongs_to :person
has_many :kids
end
class Goat::Kid
belongs_to :goat
end
Voici un résumé du schéma:
Person
first_name
last_name
Goat
name
color
Goat::Kid
nickname
age
J'aimerais que mon action #create
instancie de nouvelles instances des trois modèles avec les associations spécifiées. Cependant, bien qu'il semble que le hachage params soit transmis au contrôleur comme il se doit (en fonction des journaux de trace dans le navigateur quand il explose), l'objet Goat :: Kid
ne collecte pas le params.
irb (irb session est simplement une représentation synthétique de ce que j'essaie d'accomplir. Par conséquent, si elle n'appelle pas #save!
, ni aucune autre nécessité, ce n'est pas censé être correct. J'essaie de faire tout cela via le navigateur / formulaire 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
>> []
Maintenant, je ne peux pas comprendre comment faire en sorte que la vue transmette les paramètres à chaque objet et que le contrôleur enregistre ces paramètres dans la base de données.
Mes questions: A) est-ce un bon endroit pour utiliser nested_attributes_for
et si oui, comment puis-je le déclarer avec un espace de noms? B) Existe-t-il un moyen beaucoup plus simple et plus compréhensible de procéder?
Passer des paramètres à trois modèles a été très difficile pour moi et peu importe la quantité de documentation que j'ai lue, je ne peux pas en comprendre le sens ( #form_for
et #fields_for
). L'espace de noms complexifie davantage ceci. Merci pour toute aide!
Addendum: si je finis par déclarer
accepts_nested_attributes_for
quelle est la bonne façon d'utiliser l'argument de symbole pour un modèle en espace de nom?
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
Je ne suis pas sûr de savoir comment les modèles en mode de nom se traduisent en identificateurs de symboles. Merci!
La solution
Eh bien, c’est la première fois que je joue avec includes_nested_attributes_for
, mais avec un peu de jeu, j’ai pu obtenir quelque chose au travail.
D'abord la configuration du modèle:
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
Avec un simple contrôleur reposant:
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
Vient ensuite la forme semi-complexe:
Ensuite, la configuration du formulaire:
<% 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 %>
En regardant la source de includes_nested_attributes_for
, il semble créer une méthode appelée # {attr_name} _attributes =
. J'avais donc besoin de configurer mon < code> fields_for pour refléter cela (Rails 2.3.3). Ensuite, obtenir que has_many: kids
fonctionne avec uses_nested_attributes_for
. La méthode kids_attributes =
recherchait un tableau d'objets. Je devais donc spécifier manuellement l'association de tableau dans le formulaire et indiquer à fields_for
le type de modèle à utiliser.
J'espère que cela vous aidera.