Rails – 父/子关系

我目前正在使用标准的一对一关系来处理父/子关系:

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

是否有推荐的方法来做或者这样可以吗?

您需要调整用于实现此function的名称 – 指定关系的名称,然后告诉AR该类是什么:

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

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 

我发现我必须对@ equivalent8的解决方案做一个小改动才能使它适用于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还会在belongs_to关联上没有:optional => true声明,因为belongs_to需要在Rails 5中默认分配实例。在这种情况下,您必须分配无限数量的父项。

由于关系是对称的,我实际上发现与Toby写的不同,我更喜欢以下内容:

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

由于某种原因,“有一个父母,很多孩子”是我的思维方式,而不是“有很多父母,只有一个孩子”