J'ai un modèle polymorphe appelé adresse. Ce que j'essaye de réaliser est de havy beaucoup d'adresses liées à d'autres modèles (par exemple l'utilisateur), mais les emploie toujours comme s'il y avait un seul, et essaye de les distinguer par type.has_one choisir parmi plusieurs baser sur le paramètre
Mon projet a été conçu pour utiliser une seule adresse, donc j'ai beaucoup de morceaux de code comme User.first.address
ou User.first.address=...
dont je ne peux rien faire.
est ici sorte d'exemple:
|id|addressable_type|addressable_id| type | street |
1|User |1 | first | Foo
2|User |1 | second | Bar
3|User |1 | NULL | Other
Et ce que je veux faire est:
User.find(1).address(:second)
qui doit retourner <Address street:"Bar">
,
User.find(1).address
qui devrait revenir <Address street:"Other">
, mais User.find(1).addresses
devrait retourner la collection d'objets.
Je travaille avec un morceau de code pour ajouter le comportement d'adresse à mes modèles:
module Ext::Models::Addressable
def self.included(mod)
super
mod.class_eval do
def self.acts_as_addressable
include InstanceMethods
# Use has_many :delete_all for better performance
has_many :addresses, :as => :addressable, :dependent => :delete_all
has_one :address, :as => :addressable
end
end
end
module InstanceMethods
# I tried with this, but this doesn't even allow me to start rails becauses raises "there is no address method"
def address_with_type(type = nil)
if type
self.addresses.find(:first, :conditions => ["type = ?", type.to_s])
else
address_without_type
end
end
alias_method_chain :address, :type
end
end
J'utilise Rails et Ruby 1.9.2 2.3.14.
Si cela est possible, j'aimerais aussi savoir quelle est la meilleure façon de créer de nouvelles adresses pour un modèle donné (disons User).
Merci d'avance.
Solution
Je PRECISEE toutes les possibilités, et actuellement en projet, il n'y a que deux types d'adresses. J'ai été capable de simplifier beaucoup mon approche. Actuellement, mon self.included
ressemble:
has_many :addresses, :as => :addressable, :dependent => :delete_all
has_one :address, :as => :addressable, :conditions => {:type => nil}
has_one :foo_address, :class_name => 'Address', :as => :addressable, :conditions => {:type => "foo"}
Et maintenant, je suis en mesure de construire de nouveaux objets comme celui-ci: user.build_address(:street => "abc")
et user.build_foo_address(:street => "def")
, ce qui est exacly ce que je dois.
Merci pour votre réponse, mais j'ai réussi à résoudre le problème par une approche différente. J'ai mis à jour ma question avec un nouveau code. – blid