了解协会的“深度”

时间:2014-04-07 12:45:21

标签: ruby-on-rails ruby associations

请仔细阅读以下四行:

first_post = Discourse.create(title: 'I am the first post')
# => #<Discourse id: 56, user_id: nil, title: "I am the first post", body: nil, deleted: nil, delete_date: nil, created_at: "2014-04-07 12:34:53", updated_at: "2014-04-07 12:34:53", forum_id: nil> 
first_reply = first_post.replies.create(title: 'I am the first reply to the first post')
# => #<Discourse id: 57, user_id: nil, title: "I am the first reply to the first post", body: nil, deleted: nil, delete_date: nil, created_at: "2014-04-07 12:35:29", updated_at: "2014-04-07 12:35:29", forum_id: nil> 
second_reply = first_post.replies.create(title: 'I am the second reply to the first post')
# => #<Discourse id: 58, user_id: nil, title: "I am the second reply to the first post", body: nil, deleted: nil, delete_date: nil, created_at: "2014-04-07 12:35:41", updated_at: "2014-04-07 12:35:41", forum_id: nil> 
first_reply_reply = second_reply.retorts.create(title: 'I am the first retort to the second reply to the first retort')
# => #<Discourse id: 59, user_id: nil, title: "I am the first retort to the second reply to the fi...", body: nil, deleted: nil, delete_date: nil, created_at: "2014-04-07 12:36:53", updated_at: "2014-04-07 12:36:53", forum_id: nil> 
  • 我认为first_post有一个&#34;深度&#34;为0,因为它不是对任何事情的回复。

  • 我认为first_reply有一个&#34;深度&#34;为1,因为它是对first_post(0 + 1 = 1)

  • 的回复
  • 我认为second_reply有一个&#34;深度&#34;为1,因为它是对first_post(0 + 1 = 1)

  • 的回复
  • 我认为first_reply_reply有一个&#34;深度&#34; 2,因为它是对second_reply的回复,而是对first_post(1 + 1 = 2)的回复

等等。对first_reply_reply的回复为3.(1 + 2 = 3)

要确定每个关联的深度,我可以轻松地将一列depth添加到我的表中,然后简单地创建一个带有before_save钩子的模型方法来迭代深度,但是我想知道深度是否可以已经在铁轨中解决了。也许是一种积极的记录方法?

1 个答案:

答案 0 :(得分:1)

你应该写:

class Discourse < AR::Base

  ...

  def depth
    <parent_association> ? <parent_association>.depth + 1 || 1
  end
end

<parent_association>是您访问记录的关联,此记录是对此记录的响应。但是,这将需要许多数据库调用,因此使用before_save挂钩的方法要好得多。您还可以查看ancestry gem,它可以很好地处理树状关联(包括深度)。