2

J'ai une classe, par exemple, de voitures dont j'ai des classes héritées noir et rouge comme suit:nom de classe enfant de magasin dans la colonne de base de données en association polymorphique - rails

class Car::Black < Car 
end 

class Car::Red < Car 
end 

Maintenant, il y a une autre classe, par exemple , CarPurchase qui a beaucoup de voitures des deux variétés. Les associations sont les suivantes:

# In Black and Red models: 
has_many :car_purchases, as: :purchasable, dependent:destroy 

# In CarPurchase model: 
belongs_to :purchasable, polymorphic: true 

Maintenant, je suis en train de sauver les CarPurchases comme ceci:

black_car.car_purchases.new() # black_car is an object of class Car::Black 

Ma base de données a une colonne appelée purchasable_type. Le problème est que les enregistrements sont enregistrés avec purchasable_type « Car » et non « Car :: Black ». J'ai essayé d'enregistrer explicitement le buyerable_type lors de la création de l'enregistrement. Pas de chance. Aidez-moi, s'il vous plaît.

+0

Je pense qu'il est correct ... Vous utilisez STI et polymorphes ... dans ce cas, le type de classe de base doit être réglée ... Consultez la section des associations polymorphes pour plus détails ... http: //api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations –

+0

Je l'ai vu ce lien avant. Merci quand même! –

+0

Vérifiez cela ... Cela peut être d'une certaine aide http://www.archonsystems.com/devblog/2011/12/20/rails-single-table-inheritance-with-polymorphic-association/ –

Répondre

0

Vous pouvez faire quelque chose comme ceci:

class Car < ActiveRecord::Base 
    self.abstract_class = true 
    class Black < Car; end 
    class Red < Car; end 
end 

La raison pour laquelle il stocke Car est définie dans ActiveRecord::Associations::BelongsToPolymorphicAssociation#replace_keys Extrait:

def replace_keys(record) 
    super 
    owner[reflection.foreign_type] = record.class.base_class.name 
end 

et ActiveRecord::Inheritance::ClassMethods::base_class Extrait:

def base_class 
    unless self < Base 
    raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord" 
    end 

    if superclass == Base || superclass.abstract_class? 
    self 
    else 
    superclass.base_class 
    end 
end 

Donc, si Car est un abstract_class alors il va stocker Car::Black autre le base_class sera sage détermination à Car. Faire un Carabstract_class ne sera pas perdre la majeure partie de la magie par exemple Car::Black sait encore est table_name.

caveat utilisant Car comme abstract_class signifie qu'il ne peut pas être instanciée directement.

Par exemple:

class Car < ActiveRecord::Base 
    class Black < Car 
    end 
end 
Car::Black.base_class.name 
#=> Car 
Car::Black.table_name 
#=> "cars" 
Car.new 
#New Car record 
class Car < ActiveRecord::Base 
    self.abstract_class = true 
end 
Car::Black.base_class.name 
#=> Car::Black 
Car::Black.table_name 
#=> "cars" 
Car.new 
#=> NotImplementedError: Car is an abstract class and cannot be instantiated. 
+0

Le problème que je suis confronté ici ne consiste pas à sauver les enregistrements sous la table des voitures, mais sous la table CarPurchases. Dans la table des voitures, le nom complet de la classe est sauvegardé. Mais dans la table car_purchases, buyerable_type est Car et non Car :: Black. En outre, l'exemple mentionné ci-dessus n'est pas ce que j'essaie de mettre en œuvre. C'est juste pour expliquer le problème. J'essaie de résoudre quelque chose de similaire. –

+0

@KeerthanaRaghavan D'accord, je comprends la situation maintenant. Voir Mise à jour pour un travail potentiel – engineersmnky