Rails - отношения родителя/ребенка
В настоящее время я использую стандартное отношение "один к одному" для обработки отношений родительский/дочерний:
class Category < ActiveRecord::Base
has_one :category
belongs_to :category
end
Есть ли рекомендуемый способ сделать это или это нормально?
Ответы
Ответ 1
Вам нужно будет настроить имена, которые вы используете, чтобы получить эту работу: вы указываете имя отношения, а затем указываете AR, что класс:
class Category < ActiveRecord::Base
has_one :child, :class_name => "Category"
belongs_to :parent, :class_name => "Category"
end
Ответ 2
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
Ответ 3
Я обнаружил, что мне пришлось внести незначительные изменения в решение @equal8, чтобы он работал для 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
Без объявления foreign_key
Rails пытается найти дочерние элементы by organization_id вместо parent_id и дросселирует.
Рельсы также дросселируются без объявления :optional => true
в ассоциации belongs_to, так как имя_имя требует, чтобы экземпляр был назначен по умолчанию в Rails 5. В этом случае вам нужно было бы назначить бесконечное число родителей.
Ответ 4
Поскольку отношение симметрично, я на самом деле нахожу, что отличается от того, что написал Тоби, что я предпочитаю следующее:
class Category < ActiveRecord::Base
has_one :parent, :class_name => "Category"
belongs_to :children, :class_name => "Category"
end
По какой-то причине "имеет одного родителя, много детей" - это то, как мои мысли, а не "имеет много родителей, только одного ребенка"