【问题标题】:Rails ActiveRecord::StatementInvalid: PG::Error: ERROR: missing FROM-clause entry for tableRails ActiveRecord::StatementInvalid: PG::Error: ERROR: missing FROM-clause entry for table
【发布时间】:2012-03-13 12:22:22
【问题描述】:

我有一个复杂的 ActiveRecord 查询,我正在使用不同的范围构建它,具体取决于用户选择。我正在使用 2 颗宝石,这似乎有问题,但我找不到谁是罪魁祸首: Texticle(用于 Postgresql 完整搜索)(2.0.3) Squeel(用于 Active Record 查询中的 ruby​​ 语法) squeel (0.9.5) Arel 或 Active Record 自己

这是我的类定义:

class Event < ActiveRecord::Base
  belongs_to :entity, :class_name => "Entity", :foreign_key => :entity_id
  belongs_to :place, :class_name => "Entity", :foreign_key => :place_id

class Entity < ActiveRecord::Base
  has_many :events, :foreign_key => 'entity_id'
  has_many :events, :foreign_key => 'place_id'

最后,我的问题:

Event.joins{entity.outer}.joins{place.outer}.includes(:place).includes(:entity).textsearch('anystring'.downcase)

*这是一个 ActiveRecord::Relation 对象,使用 to_a 调用时会崩溃

这给了我以下错误:

ActiveRecord::StatementInvalid: PG::Error: ERROR:  missing FROM-clause entry for table "entities_events"
LINE 1: ... AS t1_r30, "entities"."metro_area_id" AS t1_r31, "entities_...
                                                             ^
: SELECT "events"."id" AS t0_r0, "events"."name" AS t0_r1, "events"."start_at" AS t0_r2, "events"."end_at" AS t0_r3, "events"."created_at" AS t0_r4, "events"."updated_at" AS t0_r5, "events"."entity_id" AS t0_r6, "events"."calendar_id" AS t0_r7, "events"."location" AS t0_r8, "events"."facebook_id" AS t0_r9, "events"."updated_time" AS t0_r10, "events"."privacy" AS t0_r11, "events"."venue_id" AS t0_r12, "events"."description" AS t0_r13, "events"."venue_city" AS t0_r14, "events"."venue_country" AS t0_r15, "events"."venue_state" AS t0_r16, "events"."venue_longitude" AS t0_r17, "events"."venue_latitude" AS t0_r18, "events"."yahoo_city" AS t0_r19, "events"."yahoo_country" AS t0_r20, "events"."yahoo_state" AS t0_r21, "events"."yahoo_updated_at" AS t0_r22, "events"."fb_updated_at" AS t0_r23, "events"."source_id" AS t0_r24, "events"."source_type" AS t0_r25, "events"."source_url" AS t0_r26, "events"."status" AS t0_r27, "events"."category" AS t0_r28, "events"."place_id" AS t0_r29, "events"."metro_area_id" AS t0_r30, "entities"."id" AS t1_r0, "entities"."image_url" AS t1_r1, "entities"."created_at" AS t1_r2, "entities"."updated_at" AS t1_r3, "entities"."name" AS t1_r4, "entities"."facebook_id" AS t1_r5, "entities"."link" AS t1_r6, "entities"."website" AS t1_r7, "entities"."company_overview" AS t1_r8, "entities"."mission" AS t1_r9, "entities"."category" AS t1_r10, "entities"."picture" AS t1_r11, "entities"."city" AS t1_r12, "entities"."zip" AS t1_r13, "entities"."country" AS t1_r14, "entities"."street" AS t1_r15, "entities"."state" AS t1_r16, "entities"."events_updated_at" AS t1_r17, "entities"."fblikes_updated_at" AS t1_r18, "entities"."fb_updated_at" AS t1_r19, "entities"."source_url" AS t1_r20, "entities"."source_type" AS t1_r21, "entities"."source_id" AS t1_r22, "entities"."place" AS t1_r23, "entities"."latitude" AS t1_r24, "entities"."longitude" AS t1_r25, "entities"."yahoo_city" AS t1_r26, "entities"."yahoo_state" AS t1_r27, "entities"."yahoo_country" AS t1_r28, "entities"."yahoo_updated_at" AS t1_r29, "entities"."fetched_elements_at" AS t1_r30, "entities"."metro_area_id" AS t1_r31, "entities_events"."id" AS t2_r0, "entities_events"."image_url" AS t2_r1, "entities_events"."created_at" AS t2_r2, "entities_events"."updated_at" AS t2_r3, "entities_events"."name" AS t2_r4, "entities_events"."facebook_id" AS t2_r5, "entities_events"."link" AS t2_r6, "entities_events"."website" AS t2_r7, "entities_events"."company_overview" AS t2_r8, "entities_events"."mission" AS t2_r9, "entities_events"."category" AS t2_r10, "entities_events"."picture" AS t2_r11, "entities_events"."city" AS t2_r12, "entities_events"."zip" AS t2_r13, "entities_events"."country" AS t2_r14, "entities_events"."street" AS t2_r15, "entities_events"."state" AS t2_r16, "entities_events"."events_updated_at" AS t2_r17, "entities_events"."fblikes_updated_at" AS t2_r18, "entities_events"."fb_updated_at" AS t2_r19, "entities_events"."source_url" AS t2_r20, "entities_events"."source_type" AS t2_r21, "entities_events"."source_id" AS t2_r22, "entities_events"."place" AS t2_r23, "entities_events"."latitude" AS t2_r24, "entities_events"."longitude" AS t2_r25, "entities_events"."yahoo_city" AS t2_r26, "entities_events"."yahoo_state" AS t2_r27, "entities_events"."yahoo_country" AS t2_r28, "entities_events"."yahoo_updated_at" AS t2_r29, "entities_events"."fetched_elements_at" AS t2_r30, "entities_events"."metro_area_id" AS t2_r31 FROM "events" LEFT OUTER JOIN "entities" ON "entities"."id" = "events"."entity_id" LEFT OUTER JOIN "entities" "places_events" ON "places_events"."id" = "events"."place_id" WHERE (to_tsvector('english', "events"."name"::text) @@ to_tsquery('english', 'canadiens'::text))  ORDER BY "rank0.11630770538778923" DESC
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:1106:in `async_exec'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:1106:in `exec_no_cache'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:650:in `block in exec_query'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:649:in `exec_query'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:1201:in `select'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract/database_statements.rb:16:in `select_all'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract/query_cache.rb:63:in `select_all'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/relation/finder_methods.rb:211:in `find_with_associations'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/relation.rb:170:in `exec_queries'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/relation.rb:159:in `block in to_a'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/explain.rb:40:in `logging_query_plan'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/relation.rb:158:in `to_a'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.1/lib/active_record/relation.rb:495:in `inspect'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.1/lib/rails/commands/console.rb:47:in `start'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in `start'
     from /Users/guillaumenm/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.1/lib/rails/commands.rb:41:in `<top (required)>'
     from ./script/rails:6:in `require'

If I call the to_sql method on the query, I get a working SQL statement like this :
 => "SELECT \"events\".*, ts_rank(to_tsvector('english', \"events\".\"name\"::text), to_tsquery('english', 'canadiens'::text)) AS \"rank0.7148935848557265\" FROM \"events\" LEFT OUTER JOIN \"entities\" ON \"entities\".\"id\" = \"events\".\"entity_id\" WHERE (to_tsvector('english', \"events\".\"name\"::text) @@ to_tsquery('english', 'canadiens'::text)) AND ((\"events\".\"start_at\" >= '2012-02-19T00:00:00+00:00' AND \"events\".\"start_at\" <= '2012-02-25T23:59:59+00:00')) ORDER BY \"rank0.7148935848557265\" DESC"
  • Active Record 和 ARel 是否全权负责执行完整的 sql 语句?
  • 为什么 to_sql 不产生相同的结果?
  • 有什么方法可以强制(不提供完整的 OUTER JOIN 语法)连接名称?

  • 如何确保捕获有问题的部分以填写正确的错误报告?我在调试器中迷失了方向,试图找出哪段代码写入了不正确的连接语句 ||或带有无效连接关联名称的不正确 SELECT 子句。

谢谢

【问题讨论】:

    标签: ruby-on-rails ruby activerecord arel squeel


    【解决方案1】:

    我刚刚遇到了同样的错误,这行代码:

    SampleItem.joins(:campaign_market).where(campaign_market: {market_id: current_admin_user.market_id})
    

    我的原因比上面的要简单得多,joins(:campaign_market) 是正确的,因为它是 belongs_to / 父记录,但是:

    .where(campaign_market: {market_id: current_admin_user.market_id})
    

    应该是:

    .where(campaign_markets: {market_id: current_admin_user.market_id})
    

    .where() 子句总是需要复数的表名,而不是关联名。

    【讨论】:

      【解决方案2】:

      经过多次调试,我发现问题是倍数:-(。

      首先,连接顺序必须与包含顺序相匹配。因此,这两行不会产生相同的 SQL 查询。命名别名不同。我相信这是一个我会标记的活跃记录 \ arel 问题。

      Event.joins{entity.outer}.joins{place.outer}.includes(:place).includes(:entity)
      

      不同于

      Event.joins{entity.outer}.joins{place.outer}.includes(:entity).includes(:place)
      

      然而,这个问题是透明的,直到我为我的文本搜索添加了另一个范围。我的猜测是因为 SQL 语句更改为为每列添加一个列别名。别名也使用了表别名,这与 FROM 和 JOIN 子句中的别名不同。

      更改顺序,但并没有解决我的所有问题。我最终发现了另一个问题,即我的 texticle 全文搜索的 SELECT 子句从进入数据库的查询中被扯掉了。相反,我收到此错误:

      ActiveRecord::StatementInvalid: PG::Error: ERROR:  column "rank0.8601929506100121" does not exist
      LINE 1: ...o_tsquery('english', 'canadiens'::text)) ORDER BY "rank0.860...
      

      我也认为这是 texticle、squeel 或 ActiveRecord/Arel 错误,还不确定是哪一个...

      好痛,又想自己手写SQL语句了……

      【讨论】:

      • 这太丑了。我遇到了类似的问题。
      • 我所做的是取出包含部分。这是丢弃自定义选择语句的部分。我最终通过 SQUEEL 插件使用左外连接,并为我的“包含”类手动写下我的选择语句。最后,我想限制选择以提高性能,所以我想,我正处于我想要的状态。所以最终的错误是 ActiveRecord::includes,并且间接地,Texticle 允许包含到 AR 关系对象。
      • 我们使用了一个使用 arel "where" 方法的命名范围。我们将其更改为使用旧学校的“条件”方式,并且效果很好。看起来像是一个 where 方法的错误。
      猜你喜欢
      • 2015-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-16
      • 2019-11-28
      相关资源
      最近更新 更多