Ruby on rails Rails以及如何选择ID进行子选择

Ruby on rails Rails以及如何选择ID进行子选择,ruby-on-rails,ruby-on-rails-3,activerecord,Ruby On Rails,Ruby On Rails 3,Activerecord,我是Rails新手,我知道这是一个简单的问题,但它让我发疯。 我的应用程序是用Ruby 1.9.2和Rails 3.1构建的。 我正在编写一个应用程序来管理类似酒店的房间预订。 因此,该类代表住宿: class Accommodation < ActiveRecord::Base has_many :reservations, :dependent => :destroy end 第一个查询有效,但第二个查询返回: SELECT `accommodations`.* FROM

我是Rails新手,我知道这是一个简单的问题,但它让我发疯。 我的应用程序是用Ruby 1.9.2和Rails 3.1构建的。 我正在编写一个应用程序来管理类似酒店的房间预订。 因此,该类代表住宿:

class Accommodation < ActiveRecord::Base
  has_many :reservations, :dependent => :destroy
end
第一个查询有效,但第二个查询返回:

SELECT `accommodations`.* FROM `accommodation` WHERE (id NOT IN (NULL))
我尝试将id_输出到_exclude,并且不为NULL

我做错了什么

更新:

我和阿雷尔解决了这个问题。我在下面的一条评论中写下了解决方案

ids\u to\u排除需要提取的id

试一试


您不需要为此进行两次数据库访问,您可能应该在访问期间将其作为一个范围。另外,我将把参数传递给模型方法称为坏形式,您应该明确地说明参数,以便更容易理解和维护:

class Accommodation < ActiveRecord::Base
    def self.available_between(start_date, end_date)
        joins(:reservations).where('reservations.start_date >= ? and reservations.end_date <= ?', end_date, start_date)
    end
end
或者这个:

some = Accommodation.available_between(params[:reservation_start_date], params[:reservation_end_date])
                    .where(some_other_conditions)
                    .limit(10)
                    .order(:price)

最后我找到了Arel的解决方案:

reservations = Reservation.arel_table

available_rooms = Accommodation.where(:id => reservations.project(:accommodation_id)
      .where( reservations[:start_date].lt(params[:reservation_end_date]) )
      .where( reservations[:end_date].gt(params[:reservation_start_date]) ))

感谢您的回复,但我发现了Arel避免每个do块的解决方案。我最初也考虑过加入,但由于对加入的保留为空,我放弃了这个想法。我刚刚尝试了你的方法,但没有得到任何结果,因为它构建了一个内部连接,所以没有保留的Accomodation不会appear@DrDuke:您可以联接“左外部联接保留打开…”以手动强制左联接并添加保留。id为null的where条件。是,你是对的:我可以手动强制加入,但我正在寻找一些不需要手动强制和使用to_sql的东西。无论如何,谢谢:我再次尝试了这个查询,它返回了有预订的住宿,我正在寻找相反的结果。我对Arel的查询不起作用,两个原因返回的结果都与您的相同:/这不起作用,因为我需要id不在子查询中的住宿。尝试调整查询时,我出现了一个错误:无法访问Arel::SelectManager
class Accommodation < ActiveRecord::Base
    def self.available_between(start_date, end_date)
        joins(:reservations).where('reservations.start_date >= ? and reservations.end_date <= ?', end_date, start_date)
    end
end
all_available = Accommodation.available_between(params[:reservation_start_date], params[:reservation_end_date]).all
some = Accommodation.available_between(params[:reservation_start_date], params[:reservation_end_date])
                    .where(some_other_conditions)
                    .limit(10)
                    .order(:price)
reservations = Reservation.arel_table

available_rooms = Accommodation.where(:id => reservations.project(:accommodation_id)
      .where( reservations[:start_date].lt(params[:reservation_end_date]) )
      .where( reservations[:end_date].gt(params[:reservation_start_date]) ))