我不确定这是否可行,甚至更可取
但是我想构建一个has_many关系或条件的named_scope类型关系,以便将我的痛苦简化为一个简单的关系,而不是两个。
目前我有两个模型,它们基本上包含相同的信息,并且通过相同的密钥room_id属于相同的模型房间,但是以两种不同的方式保存数据。一个包含特定日期的特定信息和一周中几天的第二个通用费率。主要障碍是,可用物品可能根本不包含特定记录的信息,在这种情况下,它需要按平均值而不是特定价格的特定价格推迟到room_rate。
任何指针或建议?感谢
+--------+-------+-------+------------+---------+-----+
| 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
填写缺少的记录,这些记录不存在答案 0 :(得分:4)
您可以在一个sql中执行此操作。但它需要你执行一个相当大的SQL。另一方面,您可以使用排序和其他好东西在一个语句中获得结果。
免责声明1:此代码为农场新鲜,空气编码,未经过任何有害测试。
免责声明2 :availables
表中2010-02-25日期的同一房间有2行。我认为那是一种失常。否则,您需要将其他参数传递给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
让我们检查availables
表中缺少的第26个的费率。
rates.keys[3] # Tue, 26 Feb 2010
rates.values[3] # 14.3999996185303
答案 1 :(得分: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
返回availbles
,如果没有此行,则从room_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
它将返回带有日期为关键字的价格的哈希