Rails - Родительские / дочерние отношения - PullRequest
12 голосов
/ 07 февраля 2011

В настоящее время я использую стандартное отношение один-к-одному для обработки родительских / дочерних отношений:

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

Есть ли рекомендуемый способ сделать это или это нормально?

Ответы [ 4 ]

20 голосов
/ 07 февраля 2011

Вам нужно настроить имена, которые вы используете, чтобы это работало - вы указываете имя отношения, а затем говорите AR, что это за класс:

class Category < ActiveRecord::Base
  has_one :child, :class_name => "Category"
  belongs_to :parent, :class_name => "Category" 
end
4 голосов
/ 10 февраля 2018

Я обнаружил, что мне пришлось внести небольшое изменение в решение @ эквивалента8, чтобы оно работало для 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 пытается найтидочерние элементы от organization_id вместо parent_id и chokes.

Rails также блокируется без объявления :optional => true в ассоциации own_to, так как assign_to требует, чтобы экземпляр был назначен по умолчанию в Rails 5. В этом случае вы должны иметьназначить бесконечное количество родителей.

4 голосов
/ 05 августа 2016

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 голосов
/ 07 октября 2011

Поскольку отношение симметричное, я нахожу, что оно отличается от того, что написал Тоби, и я предпочитаю следующее:

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

По какой-то причине «у меня один родитель, много детей», как мне кажется, а не «много родителей, только один ребенок»

...