2

我正在尝试根据关联中的查询进行复杂的搜索。

事件 belongs_to :user / 用户 has_many :events


从字面上看:

query = User.where(:name => 'Bob')
query = query.joins(:events).where('COUNT(events.start_at > #{Time.now}) = 0')

我尝试了几种方法,但似乎都没有奏效。非常感谢帮助。

提前致谢。

4

4 回答 4

0

您需要使用范围来允许这种链接:

在用户模型中:

scope :with_name, lambda { |name| where(:name => name) }

在代码中:

query = User.with_name('Bob')
query = query.joins(:events).where('COUNT(events.start_at > #{Time.now}) = 0')
于 2012-09-24T21:29:18.070 回答
0

我注意到您的查询编写方式存在一些问题,但我认为修复它们不会解决您的问题。尽管如此,希望知道这些东西会让你更接近!

首先,您需要双引号以使 Ruby 尊重您的 #{} 插值:

打开 IRB 并尝试:

1.9.3p194 :001 > 'COUNT(events.start_at > #{Time.now}) = 0'

这将输出:

"COUNT(events.start_at > \#{Time.now}) = 0"

请注意,没有任何变化,因为我们有单引号。

现在让我们尝试使用双引号,我们更接近一点:

1.9.3p194 :002 > "COUNT(events.start_at > #{Time.now}) = 0"

这次我们看到:

"COUNT(events.start_at > 2012-09-24 14:47:52 -0700) = 0"

但这仍然行不通,因为 SQL 需要在您的时间戳周围加上引号以进行比较。

我们可以手动处理,如下所示:

1.9.3p194 :003 > "COUNT(events.start_at > '#{Time.now}') = 0"

生成:

"COUNT(events.start_at > '2012-09-24 14:49:31 -0700') = 0"

但这可能不适用于所有 SQL - 我知道 Postgres 需要单引号包围文字,但 MySQL 可能更喜欢双引号,或者可能无关紧要。

处理这个问题的最好方法是让 Rails 解决这个问题。我们这样做的方式是使用 ? 我们的 SQL 查询字符串中的运算符:

where('COUNT(events.start_at > ?) = 0', Time.now)

Rails 将生成并发送到您的 SQL 数据库的输出,如下所示:

"WHERE COUNT(events.start_at > '2012-09-24 14:49:31 -0700') = 0"

希望有帮助!

于 2012-09-24T22:07:37.460 回答
0

我认为这就是您要在一行中寻找的所有内容:

Event.joins(:user).where(:users => {:name => 'Bob'}, :events => {:start_at => Time.at(0)..Time.now })
于 2012-09-24T23:54:08.513 回答
0

您不能在 WHERE 子句 afiak 中使用 COUNT。您需要对结果进行分组并使用条件仅返回您想要的结果。

query = User.where(:name => 'Bob')
query = query.joins("LEFT JOIN (SELECT events.id FROM events WHERE events.start_at > '#{Time.now.to_s(:db)}') AS events ON events.user_id=users.id").group("users.id").where("events.id IS NULL")
于 2012-09-25T00:13:23.880 回答