Rails - 父/子关系

时间:2011-02-07 01:56:27

标签: ruby-on-rails associations parent-child

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

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

是否有推荐的方法可以做到这一点还是可以吗?

6 个答案:

答案 0 :(得分:20)

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

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

答案 1 :(得分:4)

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

答案 2 :(得分:3)

我发现我必须对@ equivalent8&#39的解决方案做一个小改动才能使其适用于Rails 5(5.1.4):

manager

没有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 声明,Rails会尝试通过organization_id而不是parent_id和chokes来查找子节点。

Rails也会在belongs_to关联上没有foreign_key声明的情况下窒息,因为belongs_to需要在Rails 5中默认分配实例。在这种情况下,您必须分配无限数量的父级。

答案 3 :(得分:1)

我认为,应该是Foreign_key

class Product < ActiveRecord::Base
 has_many :children, :foreign_key => "parent_id" , :class_name => "Product"
 belongs_to :parent, :class_name => "Product" 
end

控制台:

2.4.3 :004 > product  = Product.find_by_name "BOB"

 => #<Product id: 1, name: "BOB", parent_id: nil>
2.4.3 :005 > product.children
D, [2019-11-07T14:56:14.273606 #66632] DEBUG -- :   

Product Load (0.7ms) SELECT "products".* FROM "products" WHERE "products"."parent_id" = $1  [["parent_id", 1]]

 => #<ActiveRecord::Associations::CollectionProxy 
[#<Product id: 7, parent_id: 1>, 
#<Product id: 8,  parent_id: 1>, 
#<Product id: 9, parent_id: 1>]>

答案 4 :(得分:0)

如果您已经具有模型 Category categories(在schema.rb中),则可以对模型执行此操作:

class Category < ApplicationRecord
    has_many :children, class_name: 'Category', foreign_key: :parent_id
    belongs_to :parent, class_name: 'Category', optional: true
end

这是迁移:

class AddParentIdToCategories < ActiveRecord::Migration[6.0]
  def change
    add_column :categories, :parent_id, :integer
  end
end

注意:在较新版本的Ruby中,您不需要火箭哈希=>

答案 5 :(得分:-4)

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

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

由于某种原因“有一个父母,很多孩子”是我心灵的事,而不是“有很多父母,只有一个孩子”