如何在我的模型中使用命名作用域来针对一个项目数组进行操作?

8

我知道可以根据数组进行最新书籍的查询,例如:

scope :recent_books, lambda {|since_dt| {:conditions=>{:created_at >= since_dt}}}

但是如果我有一个项目的数组,如何进行类似的查询,例如,如果我想知道是否有任何记录与[日期1、日期2、日期3等]数组中的日期匹配?

我觉得可能会有一个 collect/inject/select/map 方法来完成,但我不确定哪个是正确的。

2个回答

18

如果你将一个数组作为值传递,ActiveRecord会智能地比较是否包含在这个数组中。例如:

Book.where(:author_id => [1, 7, 42])

生成一个类似于以下 WHERE 子句的 SQL 查询:

WHERE "author_id" IN (1, 7, 42)

你可以像设置普通条件一样在scope中利用它:

class Book < ....
  # Rails 3
  scope :by_author, lambda { |author_id| where(:author_id => author_id) }

  # Rails 2
  named_scope :by_author, lambda { |author_id
    { :conditions => {:author_id => author_id} }
  }
end

然后,您可以将单个ID或ID数组传递给 by_author ,它就会正常工作:

Book.by_author([1,7,42])

иҷҪ然жҲ‘зҹҘйҒ“Rails2зҡ„named_scopeиҜӯжі•жңүдәӣеҸҳеҢ–пјҢдҪҶжҳҜеңЁRails2дёӯдҪҝз”Ёlambdaж–№жі•жҳҜеҗҰеҸҜиЎҢпјҹи°ўи°ўпјҢMichaelгҖӮ - Michael Durrant
是的。我最初在Rails 2中使用了这个语法,包括一些匹配数组的命名作用域。你只需要将where调用更改为conditions哈希即可。 - David
@MichaelDurrant 我添加了一个使用Rails 2的示例。 - David
@David 你知道如何处理元组数组吗,例如[[1,2],[3,2]]。我需要分别处理每个元组的第一个和第二个值。 - Aboozar Rajabi

5
在Rails 4中,我可以通过类似这样的作用域来检查一个数组属性中是否包含一个字符串:
scope :news, -> { where(:categories => '{news}') }

或者带一个参数:

scope :by_category, ->(category) { where(:categories => "{#{category}}") }

谢谢,这对我很有帮助。在 {news} 周围加上 { } 确实大有不同。以前不熟悉那种语法。 - Ren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接