0

これが実現可能かどうか、または望ましいかどうかはわかりません

しかし、has_many リレーションシップまたは条件付きの named_scope タイプのリレーションシップを構築して、2 つではなく 1 つの単純なリレーションシップで問題を解決したいと考えています。

現在、基本的に同じ情報を含み、同じキー room_id を介して同じモデル ルームに属している 2 つのモデルがありますが、2 つの異なる方法でデータを保持しています。1 つは特定の日付に関する特定の情報を含み、2 番目の一般的な曜日の料金は含まれています。主な障害は、Availables に特定のレコードの情報がまったく含まれていない可能性があることです。その場合、特定の日付の特定の価格ではなく、平均の room_rates に従う必要があります。

指針や提案はありますか?ありがとう

利用可能

+--------+-------+-------+------------+---------+-----+
| id     | price | spots | bookdate   | room_id | min |
+--------+-------+-------+------------+---------+-----+
| 180315 | 14.4  | 1     | 2010-02-27 | 2517    | 1   |
| 231726 | 15.84 | 1     | 2010-03-24 | 2517    | 1   |
| 180311 | 14.4  | 1     | 2010-02-23 | 2517    | 1   |
| 180313 | 14.4  | 1     | 2010-02-25 | 2517    | 1   |
+--------+-------+-------+------------+---------+-----+

客室料金

+-------+---------+-----------+-------+-----+
| id    | room_id | dayofweek | price | min |
+-------+---------+-----------+-------+-----+
| 87936 | 2517    | 0         | 14.58 | 1   |
| 87937 | 2517    | 1         | 14.58 | 1   |
| 87938 | 2517    | 2         | 14.52 | 1   |
| 87939 | 2517    | 3         | 14.52 | 1   |
| 87940 | 2517    | 4         | 14.52 | 1   |
| 87941 | 2517    | 5         | 14.4  | 1   |
| 87942 | 2517    | 6         | 14.63 | 1   |
+-------+---------+-----------+-------+-----+

それとも finder_sql メソッドでしょうか? そのような:

  has_many :aggregates,
           :class_name => 'Available',
           :finder_sql => 'SELECT room_id, price, spots, bookdate, MIN(source) 
           FROM availables
           WHERE room_id = #{id}
           GROUP BY room_id, price, spots, bookdate'

ただし、room_rates に参加して、存在しない予約日の欠落レコードを埋める必要もあります。

4

2 に答える 2

4

これは 1 つの SQL で実行できます。ただし、かなり大きな SQL を実行する必要があります。一方、並べ替えやその他の機能を使用して、1 つのステートメントで結果を取得できます。

免責事項 1:このコードは新鮮な空気でコード化されており、有害なテストを受けていません。

免責事項 2:表 には 2010 年 2 月 25 日の同じ部屋が 2 行ありavailablesます。私はそれが異常であると仮定しています。それ以外の場合は、追加のパラメーターを select ステートメントに渡して、結果をさらにフィルター処理する必要があります。

class Available < ActiveRecord::Base  
  def self.daily_rates room_id, from_date, to_date 
    date_table = (from_date..to_date).collect do |date| 
      "(SELECT  #{room_id} AS room_id, '#{date.to_formatted_s(:db)}' AS bookdate )"
    end.join(" UNION ")

    ActiveSupport::OrderedHash.new.tap do |hash|
      Available.find_by_sql( " 
         SELECT A.bookdate, IFNULL(B.price, C.price) AS price
         FROM   (#{date_table}) A
         LEFT OUTER JOIN availables B 
                ON A.room_id = B.room_id AND A.bookdate = B.bookdate
         JOIN room_rates C 
                ON A.room_id = C.room_id AND DAYOFWEEK(A.bookdate) = C.dayofweek + 1
         ORDER BY A.bookdate ASC"
      ).each do |rate_info |
        hash[rate_info.bookdate] = rate_info.price
      end
    end
  end  

end

これで、次のような呼び出しを行うことができます。

rates = Available.daily_rates(1, '2010-02-23'.to_date, '2010-02-27'.to_date)

rates.keys[0]   # Tue, 23 Feb 2010
rates.values[0] # 14.3999996185303

表にない26日のレートを確認してみましょうavailables

rates.keys[3]   # Tue, 26 Feb 2010
rates.values[3] # 14.3999996185303
于 2010-02-28T19:17:23.540 に答える
1

Room モデルにメソッドを追加するだけです。特定の日の価格を取得したいと思います。

def get_price(date)
  (self.availbles.find_by_bookdate(date) || self.room_rates.find_by_dayofweek(dayofweek(date)) ).price
end

dayofweek(date)特定の曜日を与えるものに置き換える必要があります。これは から返され、そのような行がない場合はpriceからが返されます。両方の行が欠落している場合、エラーが発生します。この問題を解決する方法についてのアイデアが得られることを願っています。availblesroom_rates

日付の範囲の場合、別の方法を追加します。

def get_prices(start_date, end_date)
  dates = (start_date..end_date).to_a
  prices = {}
  dates.each do |d|
    prices[:d] = get_price(d)
  end
  prices
end

日付がキーである価格でハッシュを返します

于 2010-02-28T17:05:43.860 に答える