这是我得到的错误:
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}不会成为数组中的字符串
答案 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")