【问题标题】:How to add conditional has_many associations如何添加条件 has_many 关联
【发布时间】:2016-12-28 10:51:20
【问题描述】:

我有以下数据库结构

任务

id   name   parent_id
1    Abc    nil
2    Pqr    1

cmets

id task_id body  
1   1      This is sample comment
2   1      This is another sample comment

task.rb

has_many :comments

comment.rb

belongs_to :task

我的要求是有一个关联,这样对于父母和孩子我都应该得到父 cmets,即对于上述两个任务我应该得到 ['This is sample comment', 'This is another sample comment']因为子任务不会有任何 cmets。

我尝试了类似以下的方法,但它不起作用

task.rb

has_many :comments,  -> (o) { where(comments: {task_id: [o.id, o.parent_id]}) }

【问题讨论】:

  • 但是不行 -- 有没有错误?

标签: ruby-on-rails ruby-on-rails-4 associations conditional-associations


【解决方案1】:

它不起作用,因为您的新条件与来自has_many 的默认条件相结合。您可以使用unscope 方法取消默认条件:

has_many :comments, -> (task) { unscope(:where).where(comments: {task_id: [task.id, task.parent_id]}) }

注意:这将破坏 Comment 模型的 default_scope(如果有的话)。

在 Rails5 中,您可以将OR 条件添加到默认条件:

has_many :comments, -> (task) { or(comments: {task_id: task.parent_id}) }

【讨论】:

  • 我试过rewhere,但它仍然结合了默认的
  • 你是对的。那没有用。我需要更多时间来找到解决方案
  • 给你!更新了答案。
  • 但它不适用于Task.where(id: [1,2]).includes(:comments)
  • 它抛出错误DEPRECATION WARNING: The association scope 'comments' is instance dependent (the scope block takes an argument). Preloading happens before the individual instances are created. This means that there is no instance being passed to the association scope. This will most likely result in broken or incorrect behavior. Joining, Preloading and eager loading of these associations is deprecated and will be removed in the future.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多