【问题标题】:Rails Associations and ScopesRails 关联和范围
【发布时间】:2013-04-11 22:39:54
【问题描述】:

我正在学习 Rails 中的范围,但在定义一些范围时遇到了一些麻烦。假设我有以下模型..

class Category < ActiveRecord::Base
  has_many :posts
  has_many :comments, :through => :post
end

class Post < ActiveRecord::Base
  belongs_to :category
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
  has_many :categories, :through => :post
  # attribute: owner
end

注意 Comment 的属性所有者。我正在尝试编写一个范围,它将返回只有我通过的所有者制作的 cmets 的类别。因此,如果一个类别有 cmets,并且这些 cmets 是由其他几个所有者制作的,则不应包括这些。我有这个工作。我得到的类别有我通过的所有者的 cmets..但我也得到了其他所有者的有 cmets 的类别。

在我的类别模型中,我有这个..

scope :comments_by_owner, lambda { |name| joins(:comments).where("comments.owner = ?", name) }

我使用

拨打电话
Category.comments_by_owner("tom")

我尝试过使用 joins 和 uniq 但没有运气..

【问题讨论】:

  • 所以您想要只包含指定所有者的 cmets 的类别?
  • 是的@Fred 没错。抱歉,直到现在我才看到您的评论。
  • 我可以看到如何在 arel 的数组上使用 Array#select 来做到这一点,但我不太确定如何覆盖 ActiveRecord 的选择,所以我不愿意提供代码。基本上,我会遍历 Category 记录,并且对于每一个记录,运行 cmets,如果我发现有 comment.name != name 的评论则拒绝该类别。剩下的就是您的单个评论者类别。

标签: ruby-on-rails


【解决方案1】:

试试这个:

scope :comments_by_owner, lambda { |name| joins(:posts => :comments).where(:comments => {:owner => name})

【讨论】:

  • 得到的结果和我的一样。它为我提供了具有所有者 = 参数 [:名称] 和所有者 = 其他人的 cmets 的类别
  • :owner 只是 Category 的一个字符串属性吗?
  • 不,所有者不在Category中,是comment的字符串属性
  • 对不起 - 我的意思是评论。 (我正在检查它是一个字符串,而不是一个单独的模型,这对于像你这样的情况更为典型。)你是否碰巧在 Category 上定义了任何可能覆盖 cmets_by_owner 的默认范围?
【解决方案2】:

似乎select 带有一个块使用Array#select。尝试遍历所有类别,选择不包含其他名称的 cmets 的类别。

def find_single_name_categories(name)
  Category.scoped.select do |category|
    category.comments.scoped.select { |comment| comment.name != name }.empty?
  end
end

【讨论】:

    猜你喜欢
    • 2016-07-23
    • 2013-06-09
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    相关资源
    最近更新 更多