2011-02-07 5 views
10

Je suis en train d'utiliser une à une norme relation pour gérer les relations parent/enfant:Rails - parents/relations enfants

class Category < ActiveRecord::Base 
    has_one :category 
    belongs_to :category 
end 

est-il un moyen recommandé de le faire ou est-ce correct?

Répondre

18

Vous aurez besoin de modifier les noms que vous utilisez pour obtenir ce travail - vous indiquez le nom de la relation, puis dire AR ce que la classe est:

class Category < ActiveRecord::Base 
    has_one :child, :class_name => "Category" 
    belongs_to :parent, :class_name => "Category" 
end 
+0

Comment trouver les catégories enfants pour les parents spécifiques. – demonchand

+0

Vous pouvez simplement utiliser parent.child? –

+0

En fait, je trouve que mon esprit groks "has_one: parent, belongs_to:: children" un arrangement plus sensible pour la même chose. – slacy

-2

Puisque la relation est symétrique, je en fait trouve que différent de ce que Toby a écrit, que je préfère les éléments suivants:

class Category < ActiveRecord::Base 
    has_one :parent, :class_name => "Category" 
    belongs_to :children, :class_name => "Category" 
end 

Pour une raison quelconque « a l'un des parents, beaucoup d'enfants » est la façon dont mes choses de l'esprit, et non pas « a beaucoup de parents, un seul enfant »

+2

Cela n'a aucun sens pour moi. Pourquoi un objet appartiendrait-il à ses enfants? De plus, l'auteur a déclaré que la relation était en tête-à-un, donc je ne comprends pas pourquoi vous le pluralisez. – LandonSchropp

+0

cela devrait être exactement l'inverse, regardez répondre -> http://stackoverflow.com/a/38791328/473040 – equivalent8

4

version has_many:

class Category < ActiveRecord::Base 
    has_many :children, :class_name => "Category" 
    belongs_to :parent, :class_name => "Category" 
end 

#migratio 
class CreateCategories < ActiveRecord::Migration 
def change 
    create_table :categories do |t| 
     t.integer :parent_id 
     t.string :title 

     t.timestamps null: false 
    end 
end 
end 

# RSpec test 
require 'rails_helper' 
RSpec.describe Category do 
    describe '#parent & #children' do 
    it 'should be able to do parent tree' do 
     c1 = Category.new.save! 
     c2 = Category.new(parent: c1).save! 

     expect(c1.children).to include(c2) 
     expect(c2.parent).to eq c1 
    end 
    end 
end 
+0

Utiliser Rails 5.1.4. J'ai trouvé que lorsque je suis le c2.parent ci-dessus me donne c1, mais c1.children me donne une erreur: ActiveRecord :: StatementInvalid (Mysql2 :: Error: Colonne inconnue 'categories.category_id' dans 'where clause': SELECT 'categories '. * FROM' categories' WHERE 'categories'.'category_id' = 5 – guero64

+0

try' has_many: enfants,: class_name => "Catégorie", foreign_key: "id" ' – equivalent8

0

Je trouve que je devais faire un changement mineur à la solution de @ equivalent8 pour le faire fonctionner pour Rails 5 (5.1.4):

class Category < ActiveRecord::Base 
    has_many :children, :class_name => "Category", foreign_key: 'parent_id' 
    belongs_to :parent, :class_name => "Category", foreign_key: 'parent_id', :optional => true 
end 

Sans la déclaration foreign_key , Rails essaie de trouver les enfants par organisation_id au lieu de parent_id et de chokes. Rails aussi étouffe sans la déclaration :optional => true sur l'association belongs_to car belongs_to nécessite une instance à assigner par défaut dans Rails 5. Dans ce cas, vous devrez assigner un nombre infini de parents.

Questions connexes