Rails 3 从作用域获取 sql

发布于 2024-11-03 19:48:29 字数 403 浏览 0 评论 0原文

有没有办法只获取一个范围的sql?所以我想做一些类似的事情:

   class Presentation < ActiveRecord::Base
      has_many :calls
      has_many :recordings, :through => :calls

      scope :with_recordings, joins(:calls).joins(:recordings)
   end

然后能够获取该范围的 sql。

Presentations.with_recordings.sql 返回整个 sql 语句,包括 SELECT 语句。我想要的只是范围添加的sql。认为应该有一种方法可以做到这一点。

Is there a way to get the sql for JUST a scope? So I want to do something like:

   class Presentation < ActiveRecord::Base
      has_many :calls
      has_many :recordings, :through => :calls

      scope :with_recordings, joins(:calls).joins(:recordings)
   end

And then be able to get the sql for that scope.

Presentations.with_recordings.sql returns the entire sql statement, including the SELECT statement. All I want is the sql added by the scope. Figure there ought to be a way to do this.

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

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

发布评论

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

评论(2

白色秋天 2024-11-10 19:48:29

我同意 ctcherry 的观点,认为这不是很有用,但话虽如此,我需要为我正在从事的项目这样做。我们需要在范围内复制 sql,以允许我们在不同类型的搜索中重用 sql。我选择从范围中提取 sql,而不是必须在两个不同的地方维护相同的 sql。

下面的代码是我想出的。它很丑,但可以在 Rails 3.0 下运行

def extract_named_scope_clause(scope, args)
  # where_clauses will return an array of clauses for an entire relationship.
  # As this is only run a single scope, we only ever care about the first.....
  clause, *bind_vars = self.send(scope, args).where_clauses.first
  # prefix 'and ' to the string, add some spaces and append any bind variables
  if clause
    [" and #{clause} ", bind_vars]
  else
    nil
  end
end

I agree with ctcherry about this not being very useful, but having said that, I needed to do this for a project I was working on. We needed to duplicate the sql in the scopes to allow us to reuse the sql across different types of searches. Rather that have to maintain the same sql in two different places, I choose to extract the sql from the scope.

The code below is what I came up with. It's ugly, but works under Rails 3.0

def extract_named_scope_clause(scope, args)
  # where_clauses will return an array of clauses for an entire relationship.
  # As this is only run a single scope, we only ever care about the first.....
  clause, *bind_vars = self.send(scope, args).where_clauses.first
  # prefix 'and ' to the string, add some spaces and append any bind variables
  if clause
    [" and #{clause} ", bind_vars]
  else
    nil
  end
end
各自安好 2024-11-10 19:48:29

这实际上没有意义,因为没有标准的方法来表示 SQL“片段”。

可以通过范围添加和操作的不同类型的 SQL“片段”实际上没有一种干净的方式来表示它们本身而不是完整 SQL 语句的一部分。片段可以是“JOIN users ON users.id =orders.user_id”,也可以是“WHERE active = 1”。如果它们不成为完整 SQL 语句的一部分,您将如何返回它们?这很可能就是为什么除了您已经发现的只返回完整 SQL 语句的机制之外,没有其他机制可以检索它们的原因。

This wouldn't really make sense, as there is no standard way to represent SQL "fragments".

The different kinds of SQL "fragments" that can be added and manipulated by a scope don't really have a clean way to be represented by themselves without being part of a complete SQL statement. A fragment could be "JOIN users ON users.id = orders.user_id" or it could be "WHERE active = 1". How would you return these without them being part of a complete SQL statement? This is most likely why there is no mechanism to retrieve them other than the one you have already discovered that just returns the complete SQL statement.

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