2012-04-12 9 views
0

私はテーブル 'Users'を持っています。 ユーザーは3つの異なる状態(state1、state2、state3)で3回(レコード)myテーブルに存在することができます。 最初のstate1が作成され、次にstate2が作成されます。 state3が存在する場合、私はstate1とstate2をもう見たくありませんが、後でそのためにテーブルに保持する必要があります。 3つのレコードはすべて同じUIDです。Selective ActiveRecord

すべてのユーザーを収集する場合、私はUser.allを使用できません(同じユーザーに対して3つの状態をすべて与えるため)。

これは私のモデルでは簡単な解決策がありますか?今、私はすべてのuuidを収集しています。そして、それぞれのuuidについて、最新の状態を確認します。次に、それらのレコードを配列に入れます。 この配列の問題は、ActiveRecordオブジェクトではなく、単に配列であることです。

@uuid = [] 
@users = [] #will contain only the latest states at the end 

User.all.each do |u| 
    @uuid << u.uuid unless @uuid.includes?(u.uuid) 
end 

@uuid.each do |u| 
    if user = User.find_by_state_and_uuid(3, u) 
    @users << user 
    elsif user = User.find_by_state_and_uuid(2, u) 
    @users << user 
    elsif user = User.find_by_state_and_uuid(1, u) 
    @users << user 
    end 
end 

このロジックをActiveRecordオブジェクトにどのように変換できますか?要するに

:User.magic_function事前に

おかげで、各UUIDの唯一の最新の状態を返すために! Wouter

答えて

0

scopesを調べましたか?各ユーザー状態のスコープを作成し、それらをクエリに使用できるようにする必要があります。

0

試してみてください。

User.get_user(state, uuid) 

そして、あなたのユーザモデルにスコープを作る:

scope :get_user, lambda { |*args| { :conditions => ["state = ? AND uuid = ?",args.first , args.second ] }} 
1

あなたが先に計画している場合、あなたは常にソートあなたの状態にし、「最高」1を返すことができます。これは、次から次への線形進行がある場合にうまく機能します。例:

user = User.where(:uuid => u).order('users.state DESC').first 

さらに複雑なトランジションの場合、このトリックを使用することはできません。 created_at時刻を最後に取得するなど、注文に別の列を使用してみることもできます。

デザインの観点からは、複数のユーザーレコードを異なる状態に持つことは非常に珍しいようです。より良い計画は、ユーザー・レコードの状態駆動部分を別の表に分割し、そこに状態をトラッキングすることです。すべてが単一のユーザー・レコードにリンクされています。