これは、いくつかの単純な抽出メソッドを使用して を書き直したものです。
def self.create_unique(attributes)
return if exists_for_user_and_target?(attributes)
return if user_is_target?(attributes)
create(attributes)
end
def self.exists_for_user_and_target?(attributes)
exists?(attributes.slice(:user_id, :target_id, :target_type))
end
def self.user_is_target?(attributes)
attributes[:target_type] == 'User' && attributes[:user_id] == attributes[:target_id]
end
この書き直しは、意図を説明するのに役立つ小さくて説明的な方法に対する私の好みを示しています。また、次のような場合にガード句を使用するのも好きcreate_unique
です。ハッピー パスは最後の行 ( create(attributes)
) で明らかにされていますが、警備員は例外的なケースを明確に説明しています。Rails 3 を前提としていますが、私のexists?
inの使用はexists_for_user_and_target?
の良い代替になると思います。find :first
代わりに一意性アクティブ モデル検証の使用を検討することもできます。