2
Class Item
    has_many :prices
    has_one  :current_price
end

Class Price
   belongs_to :item
   #date the price was set attribute
   #price attribute
end

「current_price」フィールドで現在の価格(特定のアイテムのmax()日付を保持する価格)を含む(熱心にロードされた)すべてのアイテムを見つけるにはどうすればよいですか?

例えば:

テーブルアイテム:

id = 1 | name = "the_hobbit"

テーブル価格:

id = 1 | item_id = 1 | 価格=10.99$ | 日付=2010-01-01

id = 2 | item_id = 1 | 価格=12.59$ | 日付=2009-04-23

id = 3 | item_id = 1 | 価格=19.99$ | 日付=2013-01-03

@item = Items.find(1)
@item.current_price # should print "19.99$"

編集:私の問題は「グループあたり最大のn 」と呼ばれていると思いますが、「has_one」アソシエーションでこれを適切に行う方法を理解できません...

4

3 に答える 3

2

has_oneマクロでorderオプションを使用します。

class Item
    has_many :prices
    has_one  :current_price, :order => "date DESC" 
end

もちろん、Has_oneにはSQLレベルで1つの価格しか含まれません。ただし、has_many:pricesを使用してアイテムごとのすべての価格を既にロードしている場合は、数え切れないほどの良さを備えた純粋なRubyに頼ることができます。

@item.prices.sort_by(&:date).last 

...最新の価格が表示されます。

私がそれにいる間、あなたはこれをするほうがよいでしょう:

class Item
    has_many :prices, :order => "date"
    has_one  :current_price, :order => "date DESC" 
end

@item.prices.last 

価格はSQLによって事前にソートされているため(その方法でより速く...)

于 2013-01-18T06:05:38.483 に答える
1

別の関連付けは必要ありません。カスタムメソッドを使用するだけです。

Class Item
    has_many :prices

    def current_price
        return self.prices.last
    end
end
于 2013-01-18T08:36:38.900 に答える
1

そのためにはclass_nameと外部キーを使用する必要があります。また、日付または必要なものでソートする必要があります。私の場合はバージョンで、あなたの場合はcreated_atフィールドを作成しました。

class Item
     has_one :current_price, -> { order created_at: :desc }, class_name: 'Price', foreign_key: :item_id
end

そして今、あなたがアイテムの最新の価格を取る必要があるとき、あなたはただ電話する必要があります

@item = Item.find_by(id:params [:id])。current_price

そして、それはあなたにそのアイテムの最新の価格を返します、あなたはまた使用することによってその価格をアイテムハッシュとマージすることができます

@item = Item.find_by(id:params [:id])

@ item.merge({current_price:@ item.current_price})

:current_priceそして、出力は最新の関連価格のキーと値でハッシュされます

于 2017-02-13T10:47:24.947 に答える