Rails 4.0.2在“SELECT”附近:语法错误

时间:2014-02-01 15:05:25

标签: ruby-on-rails

我正在使用此活动记录查询它运行良好

@deal = Deal.where('city_id = ?', city).where('deal_date <= ? and end_date >= ?', today, today).where('approved = ?', true).includes(:city).last

在我更新到Rails 4.0.2后,我在浏览器上看到了这个:

near "SELECT": syntax error

以下错误(网络砖服务器)

Started GET "/seattle" for 127.0.0.1 at 2014-02-01 06:36:28 -0800
  ActiveRecord::SchemaMigration Load (0.7ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Processing by DealsController#show as HTML
  Parameters: {"city_name"=>"seattle"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '00a7213ca6566ff5871c87901f2c37e781366b3b' LIMIT 1
   (0.1ms)  SELECT COUNT(*) FROM "cities" WHERE "cities"."search_name" = 'seattle'
DEPRECATION WARNING: It looks like you are eager loading table(s) (one of: deals, cities) that are referenced in a string SQL snippet. For example: 

    Post.includes(:comments).where("comments.title = 'foo'")

Currently, Active Record recognizes the table in the string, and knows to JOIN the comments table to the query, rather than loading comments in a separate query. However, doing this without writing a full-blown SQL parser is inherently flawed. Since we don't want to write an SQL parser, we are removing this functionality. From now on, you must explicitly tell Active Record when you are referencing a table from a string:

    Post.includes(:comments).where("comments.title = 'foo'").references(:comments)

If you don't rely on implicit join references you can disable the feature entirely by setting `config.active_record.disable_implicit_join_references = true`. (called from show at /Users/zekarias/Desktop/rails_project/helpon/app/controllers/deals_controller.rb:27)
  SQL (0.5ms)  SELECT "deals"."id" AS t0_r0, "deals"."name" AS t0_r1, "deals"."regular_price" AS t0_r2, "deals"."initial_discount" AS t0_r3, "deals"."max_discount" AS t0_r4, "deals"."max_threshold" AS t0_r5, "deals"."approved" AS t0_r6, "deals"."deal_date" AS t0_r7, "deals"."blurb_title" AS t0_r8, "deals"."blurb" AS t0_r9, "deals"."tipping_point" AS t0_r10, "deals"."end_date" AS t0_r11, "deals"."company_id" AS t0_r12, "deals"."created_at" AS t0_r13, "deals"."updated_at" AS t0_r14, "deals"."photo_file_name" AS t0_r15, "deals"."photo_content_type" AS t0_r16, "deals"."photo_file_size" AS t0_r17, "deals"."photo_updated_at" AS t0_r18, "deals"."price" AS t0_r19, "deals"."amount_raised" AS t0_r20, "deals"."deal_type" AS t0_r21, "deals"."city_id" AS t0_r22, "deals"."weekend" AS t0_r23, "cities"."id" AS t1_r0, "cities"."name" AS t1_r1, "cities"."search_name" AS t1_r2, "cities"."state_id" AS t1_r3, "cities"."created_at" AS t1_r4, "cities"."updated_at" AS t1_r5 FROM "deals" LEFT OUTER JOIN "cities" ON "cities"."id" = "deals"."city_id" WHERE (city_id = SELECT "cities".* FROM "cities" WHERE "cities"."search_name" = 'seattle') AND (deal_date <= '2014-02-01' and end_date >= '2014-02-01') AND (approved = 't') ORDER BY "deals"."id" DESC LIMIT 1
SQLite3::SQLException: near "SELECT": syntax error: SELECT  "deals"."id" AS t0_r0, "deals"."name" AS t0_r1, "deals"."regular_price" AS t0_r2, "deals"."initial_discount" AS t0_r3, "deals"."max_discount" AS t0_r4, "deals"."max_threshold" AS t0_r5, "deals"."approved" AS t0_r6, "deals"."deal_date" AS t0_r7, "deals"."blurb_title" AS t0_r8, "deals"."blurb" AS t0_r9, "deals"."tipping_point" AS t0_r10, "deals"."end_date" AS t0_r11, "deals"."company_id" AS t0_r12, "deals"."created_at" AS t0_r13, "deals"."updated_at" AS t0_r14, "deals"."photo_file_name" AS t0_r15, "deals"."photo_content_type" AS t0_r16, "deals"."photo_file_size" AS t0_r17, "deals"."photo_updated_at" AS t0_r18, "deals"."price" AS t0_r19, "deals"."amount_raised" AS t0_r20, "deals"."deal_type" AS t0_r21, "deals"."city_id" AS t0_r22, "deals"."weekend" AS t0_r23, "cities"."id" AS t1_r0, "cities"."name" AS t1_r1, "cities"."search_name" AS t1_r2, "cities"."state_id" AS t1_r3, "cities"."created_at" AS t1_r4, "cities"."updated_at" AS t1_r5 FROM "deals" LEFT OUTER JOIN "cities" ON "cities"."id" = "deals"."city_id" WHERE (city_id = SELECT "cities".* FROM "cities"  WHERE "cities"."search_name" = 'seattle') AND (deal_date <= '2014-02-01' and end_date >= '2014-02-01') AND (approved = 't')  ORDER BY "deals"."id" DESC LIMIT 1
Completed 500  in 123ms

SQLite3::SQLException - near "SELECT": syntax error:

1 个答案:

答案 0 :(得分:0)

该错误表示您需要在查询中添加.references(:city)

@deal = Deal.where(
                'city_id = ?', city
             ).where(
                'deal_date <= ? and end_date >= ?', today, today
             ).where(
                'approved = ?', true
             ).includes(:city).references(:city).last

仅在使用“字符串语法”即

时才需要references(:city)
where('city_id = ?', city)

另一种方法是使用哈希语法:

where(city: { city_id: city_id })

在这种情况下,Rails 4不需要references(:city)

定义连接查询时,建议在引用a列时始终包含表名或别名。这可确保您不会遇到“不明确的列名称”错误。这方面的一个例子是:

Deal.includes(:city).where('cities.city_id = ?', city_id)

请注意,where('cities.city_id = ?', city_id)具体说明了city_id表的cities,而如果您使用where('city_id = ?', city_id),那么查询处理器就不会知道哪个表的city_id要使用的列。

应用这两个修补程序后,您的最终查询将是:

@deal = Deal.where(
                    'cities.city_id = ?', city
                 ).where(
                    'deals.deal_date <= ? and deals.end_date >= ?', today, today
                 ).where(
                    'deals.approved = ?', true
                 ).includes(:city).references(:city).last