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

По какой-то причине "имеет одного родителя, много детей" - это то, как мои мысли, а не "имеет много родителей, только одного ребенка"