自我加入关联has_many和belongs_to(一)

时间:2016-08-28 03:40:35

标签: ruby-on-rails activerecord

我想建立一个有两种关系的自我加入协会

has_many belongs_to(一个)

我找到了两种方法来做到这一点,但我不确定哪一种更准确,例如在这个答案has_many and belongs_to within same model中,员工和经理之间存在关系,经理has_many员工员工belongs_to manager

解决方案是添加一个名为 manager_id 的字段,因此如果用户是管理员,那么manager_id将为null,如果员工,则manager_id将是经理的ID

协会看起来像这样:

has_many :employees, class_name: "User", foreign_key: :manager_id
belongs_to :manager, class_name: "User", foreign_key: :manager_id

我在这里找到的第二个解决方案Rails Associations - has_many => :through - but same model  具有以下关系:发布has_many related_posts related_post belongs_to post

这里的解决方案是创建两个单独的表,一个用于帖子,另一个用于related_posts,如下所示:

create_table "posts", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "related_posts", :force => true do |t|
    t.integer  "post_id"
    t.integer  "related_post_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

并且关联看起来像这样:

class Post < ActiveRecord::Base
  has_many :related_posts_association, :class_name => "RelatedPost"
  has_many :related_posts, :through => :related_posts_association, :source => :related_post
  has_many :inverse_related_posts_association, :class_name => "RelatedPost", :foreign_key => "related_post_id"
  has_many :inverse_related_posts, :through => :inverse_related_posts_association, :source => :post
end

class RelatedPost < ActiveRecord::Base
  belongs_to :post
  belongs_to :related_post, :class_name => "Post"
end

现在我不确定要走哪条路,第一个解决方案看起来很简单,想法是添加一个名为manager_id的附加字段(如果我们正在处理帖子,则可以是post_id),对于所有管理人员来说这将是空的,我想在该字段上有很多具有空值的记录似乎不正确...

第二个解决方案看起来不错,但我觉得错误的是关系has_many :inverse_related_posts_association似乎是一个related_post还有其他相关帖子/或者也许一个related_post属于很多帖子(我不确定)。

在我的情况下,我想要一些像post has_many related_posts和related_post belongs_to(一)帖子

1 个答案:

答案 0 :(得分:1)

我选择第一个选项,除非您有非常引人注目的理由采取第二种方法。这很简单明了。您可以随时重构代码。

只要列对所有记录相关,列中的空值就没有什么特别糟糕的了。在您的情况下,manager_id中的NULL意味着&#39;此人没有经理&#39; 。 这里的NULL值是否相关?我的回答是

NULL表示值未知无值。对于有经理定义的人,Rails语句@person.manager.present?将正确返回true,对于没有经理的人,false将正确返回if else。查看任何特定人员的数据库记录时,manager_id字段中的NULL将表达相同的含义。

相关问题