2009-07-15 4 views
1

:と一緒に見つける:順序とRailsはActive Recordの:私は構造を持っている。このようなグループ

class User 
    has_many :dongles 
    has_many :licences, :through => :dongles 
end 

class Dongle 
    has_many :licences 
    belongs_to :user 
end 

class Licence 
    belongs_to :dongle 
end 

をしかし、時間が経過すると、ユーザは、最終的には、各ドングルに対して複数のライセンスを取得します。合理的に、このアプリは、それぞれの最新のライセンスを要約したいと考えています。

私は単純に、このようにそれを行うことができます知っている:

user.dongles.each do |dongle| 
    licence = dongle.licences.find(:first, :order => 'created_at DESC') 
    # do something with the licence info 
end 

しかし、コレクションを介してこれを行うと、通常はそれを素朴な方法を実行してしまうのクエリの多数を回避する方法はありますか?

私はこの試みた:これは私がクエリで指定した順番で各ドングル用のライセンスが1つ返しますが、それが取る最初のものは、「ID」によって決定され、ない

user.licences.find(:all, :order => 'created_at DESC', :group => 'dongle_id') 

を。

最初のものを決定するために提供する並べ替え順を使用して、それぞれの最初のものを得る方法がありますか?

答えて

3

モデルからは、すべての関連付け情報が既に宣言されています。実際にはActiveRecord を含む単一のクエリを実行してオプションを含むことで、各ユーザーをドングルとライセンス情報にアクセスすることができます。

# Say the table name is licences and dongles. 
users = User.find(:all, 
    :include => [:dongles, :licences], 
    :order => "licences.created_at DESC, dongles.created_at DESC") 

私はあなたが、各ユーザが所有する各ドングルの最新のライセンスの概要を作成するとします。実際のニーズに合わせてループをカットすることができます。

users.each do |user| 
    # do something with your user info 
    user.dongles.each do |dongle| 
    # do something with your dongle info 
    licence = dongle.licences.first 
    # do something with the licence info 
    end 
end 

http://snippets.dzone.com/posts/show/2089

+0

コードは、私がすでに持っていたものと大差ない間、それは、クエリの数を減らすんので、これは良いです(とにかく読みやすい。) – Trejkaz

-1

でこれについての詳細を読んで、あなたは、デフォルトのスコープを試みたことがありますか? まず、ユーザーに表示されているように、has_manyに注文を追加しようとすることができます。それが動作しない場合

class User 
    has_many :dongles 
    has_many :licences, :through => :dongles, :order => 'created_at DESC' 
end 

しかし、それは実際に持っている、多くのスルー協会と連携している場合、私はわからない、多分、あなたの代わりにドングル内の関連に追加しようとすることができます。

class Dongle 
    has_many :licences, :order => 'created_at DESC' 
    belongs_to :user 
end 

2番目のオプションは、ライセンスに示されているようにデフォルトスコープで試してみることです。

class Licence 
    default_scope :order => 'created_at DESC' 
    belongs_to :dongle 
end 

その後はそれだけでそれを取得するのに十分であるべきであるuser.licenses.find(:first)

関連する問題