私のモデルの 1 つで、文字列とシンボルでも機能するように等価性を定義しました。name 属性が同じ場合、ロールは別のロール (または文字列またはシンボル) と同等です。
class Role
def == other
other_name = case other
when Role then other.name
when String, Symbol then other.to_s
end
name == other_name
end
end
等価チェックは正しく機能します。
role = Role.create name: 'admin'
role == 'admin' # => true
role == :admin # => true
しかしRole
、has_many 関係でモデルを使用すると、取得したコレクションで、include?
この等価性が認識されません。
user = User.create
user.roles << role
User.roles.include? role # => true
User.roles.include? 'admin' # => false
User.roles.include? :admin # => false
これを機能させるには、これを明示的に配列に変換する必要があります。
User.roles.to_a.include? 'admin' # => true
User.roles.to_a.include? :admin # => true
どうやら Railsinclude?
は によって返された配列のメソッドをオーバーライドしますuser.roles
。これは最低であり、ruby の仕様Enumerable#include?
(「Equailty は」を使用してテストされると明示的に述べています) に反してい==
ます。これは、から取得した配列には当てはまりませんuser.roles
。==
呼び出されることさえありません。
指定されたこの変更された動作はどこにありinclude?
ますか?
私が見逃した包含をテストする別の方法はありますか? または、毎回to_a
の実際のインスタンスを使用する必要がありますか?Role