User
というクラスがあります。これはhas_many: roles, through: user_roles
です。私はそうのようなユーザー・クラス内の関連する役割のための述語のメソッドをメタプログラミングしようとしています:クラス内のメタプログラミング述語メソッド
class User < ActiverRecord::Base
...
Role.all.pluck(:name).each do |role_name|
define_method("#{role_name}?") do
roles.map(&:name).include?(role_name)
end
end
...
end
Role.all.pluck(&:name)
ながら、既存のロール名の配列を返すん、define_method
は呼ばれることは決してありませんし、私の仕様では、未定義のメソッドで失敗します。
...
subject.roles << create(:role, name: 'foo')
expect(subject.foo?).to be true #<= undefined method `foo?' for #<User...>
...
'&'を付けずに 'pluck(:name)'にする必要があります。これはコレクションの構築物を投げ捨てて、決して呼び出されない 'define_method'につながります。 – sixty4bit
@ sixty4bit oops、updated。私は '.map'を' pluck'に置き換え、 'to_proc'を取り除くことを忘れました。しかし、まだ未定義のメソッドを返す –
ああ。その場合、私は答えがメタプログラミングの仕組みに根本的にあると考えています。あなたの 'Role.all ...'ロジックは 'User'クラスがロードされたとき、つまりテストが実行される前に実行されています。したがって、定義される唯一の方法は、 'User'がロードされる前にすでに存在していたロールのためのものです。 'User'がロードされた後にテストでロールを作成すると、以前に実行されたコードには何の影響もありません。うまくいけば意味があります... – sixty4bit