Rails教程3.2 Ch11 SQL语法

时间:2012-04-01 14:37:05

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

我正在从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

不会在followed_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 console来检查问题。

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都通过了。仍然不知道。

1 个答案:

答案 0 :(得分:0)

假设联接创建了一个字符串'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)