2010-09-07 8 views
0

Avec Rails 3 je me demandais s'il y avait une nouvelle façon de faire un has_many: par l'association avec un modèle polymorphique? Si non, quelle est la meilleure façon de le faire?A plusieurs erreurs d'association polymorphe

Voici ce que je travaille avec

class Page < ActiveRecord::Base 
end 

class Text < ActiveRecord::Base 
end 

class Picture < ActiveRecord::Base 
end 

Texte et images sont le contenu qui appartiennent à une ou plusieurs pages - Chaque page comporte un ou plusieurs éléments de contenu (texte ou image). Je voudrais être en mesure de le faire:

page.content => ["text item 1", "text item 2", "picture 1"] 
picture.pages => ["page 3", "page 7"] 

Comme je l'ai mentionné ci-dessus, je travaille avec Rails 3. Des idées?

Répondre

1

J'utilise HMT et STI:

class Page < ActiveRecord::Base 
    has_many :assets, :through => :page_components 

    def content 
    self.assets 
    end 
end 

class PageComponent < ActiveRecord::Base 
    # could also use HABTM 
    belongs_to :page 
    belongs_to :asset 
end 

class Asset < ActiveRecord::Base 
    has_many :pages, :through => :page_components 
end 

class Text < Asset 
    # inherits .pages association method from Asset 
end 

class Picture < Asset 
    # so does this. 
end 

# class Video < Asset... 
1

Il n'y a pas de différence dans Rails 3 et 2.

class Page < ActiveRecord::Base 
    belongs_to :text # foreign key - text_id 
    belongs_to :picture  # foreign key - picture_id 
end 
class Text < ActiveRecord::Base 
    has_many : pictures 
    has_many :pictures, :through => :pages 
end 
class Picture < ActiveRecord::Base 
    has_many :assignments 
    has_many :texts, :through => :pages 
end 

Deuxième idée

Votre commentaire m'a fait penser que vous pourriez avoir une tonne de content_types, ou moreso, que les content_types pourraient être capable d'être généré côté client.

Voici une alternative, pourquoi ne pas faire un seul modèle, Page - Et faire en sorte qu'il a des attributs pour refléter son content_type. Alors vous pouvez faire des relations avec eux comme si ..

@show_texts = Page.find(:all).select{ |p| p.text != nil }.collect{|p| p.id}.inspect 

Et ainsi de suite et ainsi de suite .. Juste une idée. Pour être honnête, j'essaierais de refactoriser ce code ci-dessus pour une version compatible avec SQL parce que c'est assez peu de méthodes pour frapper la DB avec.

+0

C'est seulement un à plusieurs. J'ai besoin d'un plusieurs-à-plusieurs. Je devrais également noter que dans l'exemple ci-dessus j'ai seulement 2 types de contenu, mais je pourrais avoir beaucoup plus ... – LDK

+0

Il peut être préférable d'ignorer simplement la manière polymorphe, et faites comme vous le suggérez ci-dessus. Cependant, comme j'ajoute plus de types de contenu, Page aura beaucoup de "belongs_to" déclarations ... – LDK

+0

Je ne suis pas sûr que je comprends votre image plus grande. Est-ce que les modèles vont être générés côté client? Combien de types de contenu aurez-vous? Cela vous servira au moins bien pour quelques-uns. Je vais mettre à jour ci-dessus pour une alternative. – Trip

Questions connexes