0

私は Rails の初心者で、これが単純な質問であることはわかっていますが、気が狂いそうになります。私のアプリは Ruby 1.9.2 と Rails 3.1 で構築されています。ホテルのような部屋の予約を管理するアプリを書いています。したがって、このクラスは宿泊施設を表します。

class Accommodation < ActiveRecord::Base
  has_many :reservations, :dependent => :destroy
end

そしてこれは予約です:

class Reservation < ActiveRecord::Base
  belongs_to :accommodation
end

予約にはaccommodation_id、宿泊施設の ID が保存されるという名前のフィールドがあります

ここで、特定の日付範囲で利用可能な宿泊施設を確認する必要があるため、次のメソッドを作成しました。

def self.check_availability(params)
    # This return the unavailables accommodations
    ids_to_exclude = Reservation.select(:accommodation_id).where('start_date < ? AND end_date > ?', params[:reservation_end_date], params[:reservation_start_date])

    # HERE IS THE PROBLEM
    accommodations = Accommodation.where("id NOT IN (?)", ids_to_exclude )

    accommodations
  end

最初のクエリは機能しますが、2 番目のクエリは次を返します。

SELECT `accommodations`.* FROM `accommodation` WHERE (id NOT IN (NULL))

出力しようとしましたids_to_excludeが、NULLではありません

私は何を間違っていますか?

アップデート:

これをArelで解決しました。以下のコメントに解決策を書きました

4

3 に答える 3

0

そのために2つのデータベースヒットを実行する必要はありません。おそらく、そこにいる間はスコープにする必要があります。また、モデルメソッドへの受け渡しparamsを不正な形式と呼びます。理解と維持を容易にするために、引数について明示する必要があります。

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)
于 2012-06-21T19:04:42.413 に答える
0

ids_to_excludeIDを抽出する必要があります

試す

 reservations_to_exclude = Reservation.select(:accommodation_id).where('start_date < ? AND end_date > ?', params[:reservation_end_date], params[:reservation_start_date])

 reservations_to_exclude.each do |r|
    ids_to_exclude << r.accommodation_id
 end
于 2012-06-21T18:23:19.890 に答える
0

最後に、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]) ))
于 2012-06-21T19:08:04.360 に答える