【问题标题】:Converting SQL statement to Active Record syntax将 SQL 语句转换为 Active Record 语法
【发布时间】:2015-02-09 16:24:15
【问题描述】:

我在确定以下 Postgres 查询的 Active Record 语法时遇到了一些麻烦:

SELECT *
FROM tracks
JOIN displays on displays.track_id = tracks.id
JOIN users on displays.user_id = users.id
WHERE user_id = 1
  AND displays.display is true
  AND tracks.likes_count > 200

上面的查询有效,现在我正在尝试将其转换为 activerecord 的语法,但收到错误:

PG::SyntaxError: ERROR: 在“'t'” LINE 1 处或附近出现语法错误: ...ck_id" = "tracks"."id" WHERE (displays.display is 't', track...

Track.joins(:users, :displays).where('displays.display is ?, tracks.likes_count > ?, users.id = ?', true, 200, 1)

似乎我对 displays.display is True 语句做错了,但我尝试了一些变体无济于事。

我正在使用 Activerecord-4.2.0。

我将不胜感激。

【问题讨论】:

  • is [not] trueis [not] false 被认为是后缀运算符(或有点类似,具有特殊语法)。您不能参数化其中的 true/false 部分。如果display 列不能为NULL,则可以使用displays.display = ?
  • 我明白了,你不能参数化布尔值....我怎样才能参数化其他字段并仍然设置布尔值?我尝试了您建议的几种不同的变体,但没有成功。
  • 不,您可以(通常)传递一个布尔参数,但您的情况 (is true) 很特殊。

标签: ruby postgresql activerecord


【解决方案1】:

默认情况下,ActiveRecord 不知道如何加入曲目和用户,因此请通过显示指示您要加入:

Track.joins(:displays => :users).where('displays.display is true, tracks.likes_count > ?, users.id = ?', 200, 1)

希望我能很好地记住语法:)

【讨论】:

  • 这不是我在这里做的例子吗Track.joins(:users, :displays)
  • Track.joins(:users, :displays)Track.joins(:displays => :users) 是两个不同的连接。在第一种情况下,两个内连接都使用Track 作为参考,在第二种情况下,第一个内连接考虑Track,但第二个内连接只在displaysusers 之间。
【解决方案2】:

我认为问题出在连接上,你可以试试这个:

Track.joins(displays: :users).where('displays.display = ?, tracks.likes_count > ?, users.id = ?', true, 200, 1)

您可以使用以下语法与第三个表进行连接:

Table1.joins(table2: :table3)

结果:

SELECT "table1".* 
 FROM "table1" 
 INNER JOIN "table2" ON "table2"."table_id" = "table1"."table1_id" 
 INNER JOIN "table3" ON "table3"."table2_id" = "table2"."table2_id"

able3" ON "table3"."table2_id" = "table2"."table2_id"

您可以在此处阅读有关 ActiveRecord 的连接方法的更多信息:http://guides.rubyonrails.org/active_record_querying.html#joining-tables

【讨论】:

  • 我认为这正是我在这里所做的:Track.joins(:users, :displays)
【解决方案3】:

看起来我实际上只是错过了 ANDs....derp:

Track.joins(:users, :displays).where('displays.display = ? AND tracks.likes_count > ? AND users.id = ? ', true, 200, 1)

UPDATE 同样正如@Andrius 指出的那样 Track.joins(:users, :displays) 和 Track.joins(:displays => :users) 是两个不同的连接,我想使用前者.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 2014-12-24
    相关资源
    最近更新 更多