2016-04-29 7 views
1

私はこの線に沿って簡単なActiveRecordのクエリを有する:別のモデルインスタンスと比較してActiveRecordクエリ結果をフィルタリングする方法はありますか?

similar_changes = Notification.where(change_owner: 'foo1', change_target: 'foo2', change_cancelled: false) 

各通知オブジェクトがフィールドchange_typeを有しており、私は1つの通知のchange_typeそれぞれを元に戻す逆の変更(変更するための1つの他の通知とをチェックし、別の機能を有しています私のアプリケーションの文脈では他のもの)。

この通知のchange_typeを受け取り、アレイ内の他のすべてのものと比較する必要があります。次のようなオブジェクトを参照する必要があります。similar_changes[0]['change_type']ここで、最初のインデックスは配列内の各ActiveRecordであり、2番目はNotificationオブジェクトのどのプロパティを指定する辞書です。

私は文2つのネストされたループとしている場合、手動でこれを行うことが気持ちを持っていますが、私はまた、Rubyのを知っていて、これはそれが組み込まれていなければならない何かであるように私は感じる。

私が間違っている、またはありますこれを行うには良い方法がありますか?ここで

コード(すべてこのコードはかなりそれは完璧ではないので、もし私と一緒にクマ終了していないに注意してください)です。

def self.group_similar_changes(owner, target, change_type) 
    # long query where it selects all rows where change_owner and change_target 
    # are the same as original   
    # also where cancelled is false 
    # determine if cancelled (yaml) 
    # if cancelled (do nothing) 
    similar_changes = Notification.where(
    change_owner: owner, 
    change_target: target, 
    change_cancelled: false 
) 
    similar_changes.each do |change| 
    cancel_inverse_change(change, change.change_type) 
     if change.cancelled? 
     similar_changes.delete(change) 
     end 
    end 
    end 
end 

def cancel_inverse_change(change, change_type) 
    if change.inverse?(change_type) 
    change.cancel 
    end 
end 

def inverse?(possible_inverse_change) 
    is_inverse = false 
    change_types = YAML.load_file(File.join(NotificationManager::Engine.root, 'config/change_types.yaml')) 
    if self.change_type == change_types[possible_inverse_change]['inverse'] 
    is_inverse = true 
    end 
    return is_inverse 
end 
+0

ないとして、それを書きたい、これを行うためのRubyの魔法はありません。ループを使用する。 – meagar

+1

"inverse inverse"からの "inverse"はどこにありますか? change_typesとchange_type –

+0

ああ、申し訳ありません。それはタイプミスです、申し訳ありません。 –

答えて

1

はい、similar_changesの上にループを向上させることができます。

  • ループするアレイを変更するのは混乱します。私はそれが信頼できるかどうかわからない、私はそれを決してしない!
  • 返り値eachに依存するのは慣用句ではありません。 eachは、すでに存在するEnumerableの要素に対して何かを行うために通常使用されるため、戻り値を使用するのは奇妙に見えます。

私は

similar_changes.reject do |change| 
    cancel_inverse_change(change, change.change) 
    change.cancelled? 
end 
+0

T/Fの場合、rejectメソッドが要素を削除すると仮定していますか? –

+0

はい、 'reject'は、ブロックがtrueを返す要素を削除します。 –

+0

素晴らしい、私はこれらを私のコードに取り入れ、うまく動くようにすれば答えを選びます。あなたのフィードバックのために非常にありがとう:)。 –

関連する問題