【问题标题】:Habtm join tables for a model with a self join具有自联接的模型的 Habtm 联接表
【发布时间】:2016-01-12 17:12:46
【问题描述】:

这是我的previous question

我有一个用户模型,有两个自我连接,卖家和买家。

我有一个类别模型,卖方有_and_belongs_to_many 个类别,买方也有。 如何创建迁移,以便我可以执行 Seller.categories 和 categories.buyers 等...

我以为它会像下面这样,但它不起作用......

def change
    create_table :categories_sellers do |t|
      t.references :category
      t.references :user
    end
    add_foreign_key :categories_sellers, :users, column: :trainer_id
    add_index :categories_users, [:category_id, :seller_id]
    add_index :categories_users, :seller_id
    end
  end

【问题讨论】:

  • 您希望如何在您的联接表中对sellersbuyers 进行分类?当然你只需要user_idcategory_id
  • 我以为我有两个单独的连接表,一个用于卖家/类别,一个用于买家/类别,我需要能够找到特定类别的所有卖家,因此我为什么要加入表是对的....不是吗?
  • 我知道这并不能回答你的问题,但卖家属于一个类别感觉很奇怪。产品不应该属于一个类别吗?
  • 可以简化建模以使用单表继承 (STI) 更轻松地处理此问题:api.rubyonrails.org/classes/ActiveRecord/Inheritance.html

标签: ruby-on-rails database ruby-on-rails-4 join


【解决方案1】:

要回答您的问题,您似乎只需将 t.references :user 更改为 t.references :seller。

也就是说,我强烈建议您这样建模您的项目:

module User
  extend ActiveSupport::Concern

  has_many :category_users, as: :user
  has_many :categories, through: :category_users

  # include any common methods for buyers and sellers, 
  # basically your current User model
end

class Buyer < ActiveRecord::Base
  include User
end

class Seller < ActiveRecord::Base
  include User
end

class CategoryUser < ActiveRecord::Base
  belongs_to :category
  belongs_to :user, polymorphic: true
end

class Category < ActiveRecord::Base
  has_many :category_users
  has_many :buyers, through: :category_users, source: :user, source_type: 'Buyer'
  has_many :sellers, through: :category_users, source: :user, source_type: 'Seller'
end

我知道这可能需要一些您没有预料到的更改,但在这样做时,您会获得更自然的方法,例如:

  • category.buyers
  • category.sellers
  • buyer.categories
  • seller.categories

在后台,您的连接表将包含如下列:

  • id -- 行id
  • category_id -- 当然是类别 ID
  • user_id -- 买家或卖家的id
  • user_type -- “买家”或“卖家”之一(或您认为是“用户”的任何其他类型)

运行迁移:

用户不需要,它不是模型。

买家和卖家非常简单,旧的用户模型 + 买家/卖家模型。

类别不需要,因为它已经存在。

类别用户:

def change
  create_table :category_users do |t|
    t.references :category
    t.references :user, polymorphic: true
  end
  add_index :category_users, :category_id
  add_index :category_users, [:category_id, :user_id]
  add_index :category_users, [:category_id, :user_id, :user_type]
end

我没有亲自检查过,但应该是正确的,或者接近。不过,总体原则是利用多态关联在“某种用户”(无论是买家、卖家还是您提出的任何其他类型的用户)和类别之间建立更自然的关联。然后,您无需一遍又一遍地复制相同类型的关联,因为模型略有不同。

以下是有关此方法的更多详细信息:

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多