在named_scope中封装SQL

时间:2008-09-26 03:39:32

标签: sql ruby-on-rails named-scope

我想知道是否有办法在named_scope中使用“find_by_sql”。我想将自定义sql视为named_scope,因此我可以将其链接到我现有的named_scopes。优化我经常使用的sql片段也很有用。

3 个答案:

答案 0 :(得分:10)

虽然您可以在命名范围的条件下放置任何您喜欢的SQL,但如果您再调用find_by_sql,那么“范围”就会被抛弃。

假设:

class Item
  # Anything you can put in an sql WHERE you can put here
  named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
end

这是有效的(它只是将SQL字符串粘贴在那里 - 如果你有多个它们加入了AND)

Item.mine.find :all
=> SELECT * FROM items WHERE ('user_id' = 887 and IS_A_NINJA() = 1)

然而,这不是

Items.mine.find_by_sql 'select * from items limit 1'
=> select * from items limit 1

所以答案是“不”。如果你考虑幕后发生了什么,那么这很有意义。为了构建SQL rails,必须知道它是如何组合在一起的 当您创建普通查询时,selectjoinsconditions等都会分成不同的部分。 Rails知道它可以在不影响其他所有内容的情况下添加条件(这是with_scopenamed_scope工作的方式)。

然而,使用find_by_sql,你只需要给一个大字符串。它不知道究竟发生了什么,所以它进入并添加为示波器添加所需的东西是不安全的。

答案 1 :(得分:1)

这并不能完全解决您的问题,但您可能会调查'contruct_finder_sql'。它允许您获取命名范围的SQL。

named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
named_scope :additional {
  :condtions => mine.send(:construct_finder_sql,{}) + " additional = 'foo'"
}

答案 2 :(得分:0)

确定为什么不

:named_scope:conditions => [你的sql]