#ruby-on-rails #activesupport-concern
#ruby-on-rails #activesupport-проблема
Вопрос:
Я кодирую проблему Rails, которая будет добавлена к нескольким моделям. Для дополнительной безопасности я хочу убедиться, что все модели, в которые включена эта проблема, реагируют на некоторые методы экземпляра. Назовите это контрактом, если хотите.
В любом случае, вот код, который, как я ожидал, будет работать:
module SomeConcern
extend ActiveSupport::Concern
included do
raise("The model has to respond to some_instance_method") if !self.method_defined?(:some_instance_method)
end
end
Однако это исключение всегда возникает.
- Проблемы обычно (из-за стилей) включаются в верхнюю часть модели; однако на данный момент мы еще не достигли
def
вызова в модели, поэтому метод экземпляра еще не определен. - Даже если мы включим проблему в самый низ модели (чего я действительно хотел бы избежать для лучшего взаимодействия с разработчиками), я заметил, что if
some_instance_method
на самом деле является именем столбца, он будет реагировать толькоtrue
method_defined?
в том случае, если я создам экземпляр модели заранее.
С a binding.pry
внутри included
блока это происходит:
self.method_defined?(:some_column_name)
=> false
self.new
self.method_defined?(:some_column_name)
=> true
Итак, учитывая все это, каков наилучший способ вызвать исключение, когда проблема включена в модель, чтобы убедиться, что один экземпляр этой модели действительно реагирует на некоторые методы, которые я хочу проверить?
Ответ №1:
Вы могли бы определить значение по умолчанию some_instance_method
в SomeConcern
, какая raise
ошибка при его вызове, если у вас нет метода с тем же именем в SomeModal
:
module SomeConcern
extend ActiveSupport::Concern
def some_instance_method
raise("The model has to respond to some_instance_method")
end
end
class SomeModal
include SomeConcern
def some_instance_method
do_the_work
end
end