将SQL封装在named_scope中

发布于 2024-07-05 10:17:30 字数 115 浏览 10 评论 0原文

我想知道是否有办法在命名范围内使用“find_by_sql”。 我想将自定义sql视为named_scope,这样我就可以将其链接到现有的named_scope。 它对于优化我经常使用的 sql 片段也很有好处。

I was wondering if there was a way to use "find_by_sql" within a named_scope. I'd like to treat custom sql as named_scope so I can chain it to my existing named_scopes. It would also be good for optimizing a sql snippet I use frequently.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧街凉风 2024-07-12 10:17:30

虽然您可以将任何您喜欢的 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 字符串粘贴在那里 - 如果你有多个 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,你只需给rails一个大字符串。 它不知道什么东西会去哪里,因此它不安全地进入并添加范围正常工作所需的内容。

While you can put any SQL you like in the conditions of a named scope, if you then call find_by_sql then the 'scopes' get thrown away.

Given:

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

This works (it just sticks the SQL string in there - if you have more than one they get joined with AND)

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

However, this doesn't

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

So the answer is "No". If you think about what has to happen behind the scenes then this makes a lot of sense. In order to build the SQL rails has to know how it fits together.
When you create normal queries, the select, joins, conditions, etc are all broken up into distinct pieces. Rails knows that it can add things to the conditions without affecting everything else (which is how with_scope and named_scope work).

With find_by_sql however, you just give rails a big string. It doesn't know what goes where, so it's not safe for it to go in and add the things it would need to add for the scopes to work.

转角预定愛 2024-07-12 10:17:30

这并不能完全解决您所问的问题,但您可以调查“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'"
}

This doesn't address exactly what you asked about, but you might investigate 'contruct_finder_sql'. It lets you can get the SQL of a named scope.

named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
named_scope :additional {
  :condtions => mine.send(:construct_finder_sql,{}) + " additional = 'foo'"
}
如痴如狂 2024-07-12 10:17:30

当然为什么不

:named_scope :conditions => [你的sql]

sure why not

:named_scope :conditions => [ your sql ]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文