代码之家  ›  专栏  ›  技术社区  ›  holden

聚合条件有多个Rails关联

  •  0
  • holden  · 技术社区  · 14 年前

    我不确定这是否可行,甚至更可取

    但我想建立一个has_-many关系或一个条件命名的_-scope类型的关系,以减轻我的痛苦成为一个简单的关系,而不是两个。

    目前我有两个模型,它们基本上包含相同的信息,并且通过相同的密钥室id属于相同的模型室,但是以两种不同的方式保存数据。其中一个包含特定日期的特定信息,以及一周中几天的第二个通用费率。主要的障碍是可用的可能根本不包含特定记录的信息,在这种情况下,它需要遵从给定日期的平均房价而不是具体价格。

    有什么建议吗?谢谢

    可用的

    +--------+-------+-------+------------+---------+-----+
    | 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'
    

    但它还需要通过加入房价来填写不存在的预订日期的缺失记录

    2 回复  |  直到 14 年前
        1
  •  4
  •   Harish Shetty    14 年前

    您可以在一个sql中完成此操作。但它需要您执行一个相当大的sql。另一方面,通过排序和其他优点,您可以在一个语句中获得结果。

    免责声明1: 本规范为农场新鲜空气编码,未经任何有害测试。

    免责声明2: 2010年2月25日同一房间有两排 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号的价格 可用的 表。

    rates.keys[3]   # Tue, 26 Feb 2010
    rates.values[3] # 14.3999996185303
    
        2
  •  1
  •   klew    14 年前

    我只想在房间模型中添加方法。我想你想知道一天的价格。

    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
    

    它将返回带有价格的哈希值,其中日期是一个键