Travailler sur un exemple simple de relations polymorphes double face en utilisant le plugin has_ many_ polymorphs ActiveRecord. J'ai deux classes, "chats" et "chiens", qui peuvent avoir des "amitiés" les uns avec les autres, donc trois classes en tout: "chats", "chiens" et "amitiés". Un chat peut être ami avec un chien (oui, ça arrive!) Et bien sûr aussi avec d'autres chats. La même chose vaut pour les chiens. Voici mes modèles:Comment définir has_many_polymorphs Les paramètres CRUD reposfully
class Cat < ActiveRecord::Base
validates_presence_of :name
end
class Dog < ActiveRecord::Base
validates_presence_of :name
end
class Friendship < ActiveRecord::Base
belongs_to :left, :polymorphic => true
belongs_to :right, :polymorphic => true
acts_as_double_polymorphic_join(
:lefts => [:cats, :dogs],
:rights => [:dogs, :cats]
)
end
J'ai essayé pendant des jours pour obtenir ce travail et je dois manquer quelque chose d'évident. Lorsque je tente de créer une nouvelle amitié que je reçois:
NameError (wrong constant name cats):
(eval):7:in `before_save'
app/controllers/friendships_controller.rb:45:in `create'
ou
NameError (wrong constant name dogs):
(eval):7:in `before_save'
app/controllers/friendships_controller.rb:45:in `create'
Ceci est mon schema.rb:
ActiveRecord::Schema.define(:version => 20090613051350) do
create_table "cats", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "dogs", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "friendships", :force => true do |t|
t.integer "left_id"
t.string "left_type"
t.integer "right_id"
t.string "right_type"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Je suis en train de créer une nouvelle "amitié" en faisant un POST à, par exemple,/cats/3/relations avec une route qui obtient left_type et left_id de l'URL et le right_type et right_id des paramètres POST. Le routage déclenche la méthode #create du contrôleur friendships_ correctement et les params résultant ressembler à ceci:
Parameters: {
"authenticity_token"=>"gG1eh2dXTuRPfPJ5eNapeDqJu7UJ5mFC/M5gJK23MB4=",
"left_type"=>"cats",
"right_type"=>"dogs",
"left_id"=>"3",
"right_id"=>"1"
}
Pour des raisons qui ne relèvent pas de cette question, je veux séparer entre « gauche » et « droits » dans de telle sorte que je puisse suivre à qui l'amitié a été postée (d'où les «gauches» et «droits»), mais peut-être mon modèle n'est pas la bonne façon d'accomplir cela? Ai-je mal compris le but du plugin has_ many_ polymorphs? Voici l'action #create du contrôleur friendships_:
def create
@friendship= Friendship.new(
:left_type => params[:left_type],
:left_id => params[:left_id],
:right_type => params[:right_type],
:right_id => params[:right_id]
)
respond_to do |format|
if @friendship.save
format.xml {
render :xml => @friendship,
:status => :created,
:location => @friendship
}
else
format.xml {
render :xml => @friendship.errors,
:status => :unprocessable_entity
}
end
end
end
Et enfin mon routes.rb:
map.resources :friendships
map.resources :cats do |cat|
cat.resources :friendships, :path_prefix => "/:left_type/:left_id"
end
map.resources :dogs do |dog|
dog.resources :friendships, :path_prefix => "/:left_type/:left_id"
end
Comme je l'ai dit, je l'ai passé beaucoup de temps sur mon propre pour essayer de comprendre ce mais la documentation qui existe est soit périmée, trop générale ou trop avancée - ou, dans certains cas, les trois à la fois. Ce n'est pas facile de commencer sur ce truc RoR, je peux vous le dire! Je sais qu'il y a des avantages réels de la maîtrise du RoR donc je vais persister, mais certains de ces casse-tête sont si mauvais que je commence à avoir un patch chauve. Je sais qu'il y a beaucoup de développeurs expérimentés de Ruby/Rails et j'espère que quelqu'un pourra sortir du bois et expliquer ce truc pour nous, simples mortels.
Merci à l'avance,
JS
Merci James, cela ressemble à une solution beaucoup plus simple! Mais ne commencerait-il pas à devenir un peu maladroit quand j'ai plus de deux classes de base? Qu'est-ce que je devais ajouter une troisième classe, disent les porcs, aux deux autres? En outre, ce modèle ne me permettrait pas de voir quelle partie a été l'initiateur de la relation (les «gauches» dans mon exemple ci-dessus), ou est-ce que j'ai mal compris quelque chose? –