【问题标题】:Rails Tutorial 3.2 Ch11 SQL syntaxRails 教程 3.2 Ch11 SQL 语法
【发布时间】:2012-04-16 21:40:12
【问题描述】:

我正在通过 rails 教程学习 rails。我在Section 11.3.1 中遇到了问题,代码清单11.44:

def self.from_users_followed_by(user)
  followed_user_ids = user.followed_user_ids.join(', ')
  where("user_id IN (?) OR user_id = ?", followed_user_ids, user)
end

不会在 follow_user_ids 中返回 user_id。

在stackoverflow上搜索后,我找到了解决方案here,上面说只要去掉“join”方法就可以了。

但是我很好奇为什么在删除“join”方法之前运行RSPEC没有错误。

在清单 11.41 中:

subject { Micropost.from_users_followed_by(user) }

it { should include(own_post) }
it { should include(followed_post) }

如果“join”方法会使SQL语句出错,为什么RSPEC通过了?

有人遇到同样的问题吗?

2012.04.03 更新

我使用 Rails 控制台检查问题。

user = User.first
ids = ids = user.following_users.map(&:id).join(', ')

得到了

User Load (2.6ms)  SELECT "users".* FROM "users" INNER JOIN "follows" ON
"follows"."followable_id" = "users"."id" AND "follows"."followable_type" = 'User' WHERE    
"follows"."blocked" = 'f' AND "follows"."follower_id" = 1 AND "follows"."follower_type" 
= 'User' AND "follows"."followable_type" = 'User'
=> "6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29,    
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 
52, 55, 56, 5"

然后是 SQL

Collection.where("user_id IN (?)", ids)

结果是

Collection Load (0.7ms)  SELECT "collections".* FROM "collections" WHERE (user_id IN 
('6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 
52, 55, 56, 5')) ORDER BY collections.created_at DESC
=> []

返回一个空数组。

但我的所有 rspec 都通过了。还是不知道。

【问题讨论】:

  • 测试环境是否也在postgres上运行?
  • 测试和开发环境运行在 SQLite 上。

标签: ruby-on-rails ruby-on-rails-3 railstutorial.org


【解决方案1】:

假设连接创建了一个字符串'1,2,3',那么也许您希望join("','") 拥有('1','2','3'),但我认为这不会起作用 - 我确定 PostgreSQL 不喜欢将 ID 作为字符串。

或者:

Squeel 是一个很好的 SQL 语法 gem,您可以在其中使用:

user = User.first
ids = user.following_users.map(&:id)
Collection.where{(user_id.like_any ids)}

这将允许您传入整数数组,Squeel 将设置查询:

SELECT "collections".* FROM "collections" WHERE (("collections"."user_id" LIKE 1 OR "collections"."user_id" LIKE 2 OR "collections"."user_id" LIKE 3))

编辑:您也可以使用语法:

ids = User.first.following_users.pluck(:id)
Collection.find_by_user_id(ids)

【讨论】:

  • 感谢您的回复。但我真正关心的是为什么我运行Rspec测试时它通过了,但运行应用程序时却无法运行。
  • PostgreSQL 不喜欢以字符串形式给出的 ID AFAIK。纯粹的猜测,但你为什么不试试我的建议,用 Squeel。
  • 我会试试的。非常感谢。
  • 如果您觉得 1up 有用,我可以得到它吗?帮助世界运转;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多