将SQL封装在named_scope中
时间:2020-03-06 14:45:51 来源:igfitidea点击:
我想知道是否有一种方法可以在named_scope中使用" find_by_sql"。我想将自定义sql视为named_scope,因此可以将其链接到我现有的named_scopes。这对于优化我经常使用的sql代码段也将是一件好事。
解决方案
确定为什么不
:named_scope:conditions => [sql]
虽然我们可以将任何喜欢的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连接在一起,它将SQL字符串留在其中)
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,必须知道它如何组合在一起。
当我们创建普通查询时,"选择","联接","条件"等都被分解为不同的部分。 Rails知道它可以将条件添加到条件中,而不会影响其他所有条件(with_scope和named_scope的工作方式)。
但是,使用find_by_sql
,我们只需给rails一个大字符串。它不知道去哪儿,所以进入它并添加为使作用域工作所需添加的内容并不安全。
这不能完全满足要求,但是我们可以调查" 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'" }