如何摆脱rails中的搜索查询错误“无法识别的令牌:”#“”?

时间:2016-07-27 05:20:03

标签: ruby-on-rails ruby sqlite rails-console

这是我得到的错误:

SQLite3::SQLException: unrecognized token: "#": SELECT "posts"."id" AS
t0_r0, "posts"."title" AS t0_r1, "posts"."content" AS t0_r2, 
"posts"."created_at" AS t0_r3, "posts"."updated_at" AS t0_r4, 
"posts"."user_id" AS t0_r5, "posts"."course_id" AS t0_r6, 
"courses"."id" AS t1_r0, "courses"."name" AS t1_r1, 
"courses"."created_at" AS t1_r2, "courses"."updated_at" AS t1_r3, 
"courses"."major_id" AS t1_r4, "courses"."user_id" AS t1_r5 FROM 
"posts" LEFT OUTER JOIN "courses" ON "courses"."id" = 
"posts"."course_id" WHERE (courses.name IN (#{s},#{s}))  ORDER BY 
posts.created_at DESC

对于此查询:

@posts = Post.includes(:course).where("courses.name IN (#{@user.courses.map(&:name).collect { |s| '#{s}'  }.join(',') })").references(:courses).order("posts.created_at DESC")

我不明白为什么#{s}不会成为数组中的字符串

2 个答案:

答案 0 :(得分:1)

问题的原因是字符串插值在单引号内不起作用。您需要使用"#{s}"

但是,作为第一个改进,将变量转换为字符串的首选方法只是调用s.to_s。也就是说,name听起来像已经一个字符串,因此可能会消除整个映射过程。

您也不应该使用字符串插值来构建查询。使用参数化查询,为Rails提供字符串数组,并让它为您完成工作:

@posts = Post.includes(:course).where('courses.name IN (?)', @user.courses.pluck(:name))

请注意,要从一组结果中选择一个列,使用pluck(:field)map(&:field)更快 map方法选择所有列,为结果实例化整个ActiveRecord模型,然后在将集合减少到单个字段时抛出所有这些工作。 pluck 选择必填字段,并且不为结果集构建AR对象。

答案 1 :(得分:0)

您的回答确实有帮助,我遇到了字符串iterpolation的问题,有效的代码是

@posts = Post.all.includes(:course).where("courses.name IN (#{@user.courses.map(&:name).collect { |s| "'#{s}'"  }.join(',') })").references(:course).order("posts.created_at DESC")