活动记录:基于关联中的另一个查询进行查询

时间:2012-09-24 21:18:07

标签: sql ruby-on-rails activerecord

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

事件belongs_to:user / User has_many:events


沿着字面线:

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

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

提前致谢。

4 个答案:

答案 0 :(得分:0)

您需要使用scopes来实现这种链接:

在用户模型中:

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')

答案 1 :(得分: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"

希望有所帮助!

答案 2 :(得分:0)

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

Event.joins(:user).where(:users => {:name => 'Bob'}, :events => {:start_at => Time.at(0)..Time.now })

答案 3 :(得分: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")