2012-02-23 35 views
9

Tôi đã truy vấn ActiveRecord phức tạp mà tôi đang xây dựng với các phạm vi khác nhau, tùy thuộc vào lựa chọn của người dùng. Tôi đang sử dụng 2 đá quý, có vẻ như có vấn đề với nhau, nhưng tôi không thể tìm ra ai là thủ phạm giữa: Texticle (cho tìm kiếm đầy đủ Postgresql) (2.0.3) Squeel (để sử dụng cú pháp ruby ​​trong truy vấn Bản ghi Hoạt động) squeel (0.9.5) Arel hoặc Active Record tựRails ActiveRecord :: StatementInvalid: PG :: Lỗi: ERROR: thiếu mục nhập mệnh đề FROM cho bảng

Dưới đây là các lớp học định nghĩa của tôi:

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' 

Và cuối cùng, truy vấn của tôi:

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

* Đây là một đối tượng ActiveRecord :: Quan hệ, mà cr tro khi gọi nó với to_a

này mang lại cho tôi những lỗi sau:

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" 
  • là Active Record và Arel đầy đủ trách nhiệm để thực hiện báo cáo kết quả đầy đủ sql?
  • Tại sao to_sql không tạo ra kết quả tương tự?
  • Bất kỳ cách nào để buộc (không đưa ra cú pháp OUTER JOIN đầy đủ) tên tham gia?

  • Làm cách nào tôi có thể chắc chắn chụp được mảnh có vấn đề để điền vào báo cáo lỗi thích hợp? Tôi khá bị mất trong trình gỡ rối của tôi cố gắng tìm những gì đoạn mã viết câu lệnh nối không đúng || hoặc mệnh đề SELECT không chính xác với tên hiệp hội nối không hợp lệ.

Cảm ơn

Trả lời

5

Sau nhiều gỡ lỗi, tôi thấy vấn đề này là bội số :-(.

Thứ nhất, tham gia trật tự phải phù hợp với bao gồm trật tự. Do đó, 2 dòng, doesn' t sản xuất các truy vấn SQL giống nhau. Đặt tên bí danh khác nhau. tôi tin rằng đây là một hoạt động kỷ lục \ AREL vấn đề mà tôi sẽ gắn cờ.

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

khác với

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

Tuy nhiên, vấn đề này là minh bạch, cho đến khi tôi thêm một phạm vi khác cho tìm kiếm văn bản của mình. Tôi đoán là vì câu lệnh SQL đã thay đổi để thêm một bí danh cột cho mỗi cột. Bí danh cũng sử dụng bí danh bảng, sau đó khác biệt với tên trong mệnh đề FROM và JOIN.

Thay đổi thứ tự, không khắc phục được tất cả sự cố của tôi. Tôi đã kết thúc tìm một vấn đề khác mà mệnh đề SELECT của văn bản tìm kiếm văn bản đầy đủ của tôi bị tách khỏi truy vấn đi đến DB. Thay vào đó, tôi nhận được lỗi này:

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

Tôi cũng tin rằng đây là một trong hai một texticle, squeel hoặc ActiveRecord/Arel lỗi, không chắc chắn mà người ta chưa ...

Vì vậy, đau đớn tôi muốn viết lên các câu lệnh SQL của riêng tôi bằng tay một lần nữa ...

+0

Thật đáng sợ. Tôi đang gặp vấn đề tương tự. – jevy

+1

Điều tôi đã làm là lấy phần bao gồm. Đây là mảnh mà ném đi báo cáo lựa chọn tùy chỉnh. Tôi đã kết thúc bằng cách sử dụng bên ngoài tham gia bên ngoài thông qua các plugin SQUEEL, và viết xuống của tôi lựa chọn báo cáo bằng tay cho tôi "bao gồm" các lớp học. Cuối cùng, tôi muốn giới hạn lựa chọn cho hiệu suất, vì vậy tôi đoán, tôi đang ở điểm tôi muốn. Vì vậy, lỗi, cuối cùng, là ActiveRecord :: bao gồm, và gián tiếp, Texticle cho phép bao gồm đối tượng quan hệ AR. – xlash

+0

Chúng tôi đã sử dụng phạm vi được đặt tên đang sử dụng phương thức "ở đâu" của arel. Chúng tôi đã thay đổi nó để sử dụng cách "điều kiện" trường học cũ và nó hoạt động tốt. Trông giống như một lỗi phương pháp ở đâu đó. – jevy

16

Tôi vừa mới có những lỗi tương tự đưa ra đối với tôi, với dòng mã này:

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

nguyên nhân của tôi là đơn giản hơn nhiều so với cái trên, joins(:campaign_market) là đúng vì nó là một kỷ lục belongs_to/mẹ Tuy nhiên:

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

cần phải có được:

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

Mệnh đề .where() luôn muốn tên bảng đa nguyên, không phải tên liên kết.

Các vấn đề liên quan