2011-02-07 11 views
10

obecnie używam standardowego relacji jeden-do-jednego do obsługi relacji rodzic/dziecko:Rails - Rodzic/dziecko relacje

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

Czy jest zalecany sposób to zrobić czy to w porządku?

Odpowiedz

18

Będziesz musiał dostosować nazwy używasz uzyskać tej pracy - podać nazwę związku, a następnie powiedzieć AR jaka klasa jest:

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

Jak znaleźć kategorie dzieci dla konkretnych rodziców. – demonchand

+0

Możesz po prostu użyć parent.child? –

+0

W rzeczywistości uważam, że mój umysł groksuje "has_one: parent; belongs_to:: children" bardziej rozsądny układ dla tego samego. – slacy

-2

Ponieważ relacja jest symetryczna, ja faktycznie okaże się, że różni się od tego, co Toby napisał, że wolę, co następuje:

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

Z jakiegoś powodu „ma jedno z rodziców, wiele dzieci” to sposób mój umysł rzeczy, a nie „ma wiele rodziców, tylko jedno dziecko”

+2

To nie ma dla mnie żadnego sensu. Dlaczego obiekt należy do jego dzieci? Poza tym autor stwierdził, że związek jest jeden do jednego, więc nie rozumiem, dlaczego go pluralizujesz. – LandonSchropp

+0

to powinno być dokładnie odwrotnie, spójrz na odpowiedź -> http://stackoverflow.com/a/38791328/473040 – equivalent8

4

wersja 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

Korzystanie z szyn 5.1.4. Znalazłem, że gdy postępuję zgodnie z powyższym c2.parent daje mi c1, ale c1.children daje mi błąd: ActiveRecord :: StatementInvalid (Mysql2 :: Błąd: Nieznana kolumna "categories.category_id" w "gdzie klauzula": SELECT 'kategorie '. * FROM' categories' WHERE 'categories''category_id' = 5 – guero64

+0

wypróbuj' has_many: children,: class_name => "Category", foreign_key: "id" ' – equivalent8

0

Okazało się, że musiałem dokonać drobnych zmian do użytkownika @ equivalent8 rozwiązania, aby pracować dla 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 

Bez deklaracji foreign_key , Railsy próbują znaleźć dzieci według id_organizacji zamiast parent_id i dławików.

Szyny są również dławiki bez deklaracji :optional => true w stowarzyszeniu belongs_to, ponieważ belongs_to wymaga, aby instancja została domyślnie przypisana w Rails 5. W tym przypadku konieczne byłoby przypisanie nieskończonej liczby rodziców.