当要包含的模型与基础模型没有直接关联时,如何调用include(左连接)?

时间:2011-11-25 04:51:56

标签: mysql ruby-on-rails activerecord left-join

我想加入,预订,子预订和客户三种模式。预订has_many sub_bookings也是预订属于(也可能不是)客户。我想列出client.name排序的所有sub_book。我需要加入预订和分包以及预订和客户之间的包含关系。我尝试了以下内容,但它没有用。

SubBooking.joins(:booking).includes(:booking=>:client).order('client.name')

模型如下

class Booking < ActiveRecord::Base
  belongs_to :client
  has_many :sub_bookings
  ...
end

class SubBooking < ActiveRecord::Base
  belongs_to :booking
  ...
end

class Client < ActiveRecord::Base
  has_many :bookings
  ...
end

更准确地说,我想要生成的SQL是这样的

SELECT * FROM sub_bookings 
INNER JOIN bookings ON bookings.id = sub_bookings.booking_id
LEFT JOIN Clients ON bookings.client_id = clients.id
ORDER BY client.name

1 个答案:

答案 0 :(得分:0)

我认为你的代码中有拼写错误。我已经创建了您在问题中描述的应用程序,并尝试了一些简单的查询。接下来,我尝试了下面输出中第一行看到的示例查询。

Loading development environment (Rails 3.1.3)
ruby-1.9.2-p290 :001 > SubBooking.joins(:booking).include(:booking=>:client).order('client.name').to_sql
NoMethodError:   SubBooking Load (0.1ms)  SELECT "sub_bookings".* FROM "sub_bookings" INNER JOIN "bookings" ON "bookings"."id" = "sub_bookings"."booking_id"
undefined method `include' for []:ActiveRecord::Relation
        from /home/devin/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.1.3/lib/active_record/relation.rb:459:in `method_missing'
        from (irb):1
        from /home/devin/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/commands/console.rb:45:in `start'
        from /home/devin/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/commands/console.rb:8:in `start'
        from /home/devin/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/commands.rb:40:in `<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>'
ruby-1.9.2-p290 :002 > SubBooking.joins(:booking).includes(:booking=>:client).order('client.name').to_sql
 => "SELECT \"sub_bookings\".* FROM \"sub_bookings\" INNER JOIN \"bookings\" ON \"bookings\".\"id\" = \"sub_bookings\".\"booking_id\" ORDER BY client.name"
ruby-1.9.2-p290 :003 >

如你所见,它会抛出一个很好的错误,这是你可能已经看到的,只需更正这个调用:

SubBooking.joins(:booking).include(:booking=>:client).order('client.name') 

对此:

SubBooking.joins(:booking).includes(:booking=>:client).order('client.name')

解决了错误。

如果您希望在GitHub over here上看到我使用的代码。如果您还有其他问题,请与我们联系。

此致 德文姆