В поисках способа достижения того же элемента управления, предложенного @Nate (избегая любого вида создания / обновления / удаления), но используя его только в определенных частях моего приложения и для всех моделей одновременно, я создал этот Ruby * 1001. * уточнение
module ReadOnlyRailsMode
CLASS_METHODS = ActiveRecord::Base.methods
.select { |m| m =~ /(update|create|destroy|delete|save)[^\?]*$/ }
INSTANCE_METHODS = ActiveRecord::Base.instance_methods
.select { |m| m =~ /(update|create|destroy|delete|save)[^\?]*$/ }
refine ActiveRecord::Base.singleton_class do
CLASS_METHODS.each do |m|
define_method(m) do |*args|
raise ActiveRecord::ReadOnlyRecord
end
end
end
refine ActiveRecord::Base do
def readonly?; true; end
INSTANCE_METHODS.each do |m|
define_method(m) do |*args|
raise ActiveRecord::ReadOnlyRecord
end
end
end
end
И использовать его только в определенной части кода:
class MyCoolMailerPreview < ActionMailer::Preview
using ReadOnlyRailsMode
end
(Это реальный вариант использования, я искал способ избежать людей, создающих и редактирующих реальные записи из ActionMailer :: Previews, потому что я хочу разрешить предварительный просмотр в производстве, но если по ошибке кто-то создает предварительный просмотр, который изменяет реальные данные, это стало бы хаосом).
Код немного некрасиво переопределяет все методы (create, create !, и т. Д.), Потому что цель состоит в том, чтобы изменить поведение всех моделей, и обратные вызовы типа "before_create" не могут использоваться для этой цели, поскольку быть локально только для «использования» области, изменяя все приложение.
Этот подход работает для меня, я могу явно заблокировать все эти методы для всех моделей только в одном классе и не связываться с остальной частью приложения. К сожалению, до сих пор уточнения не применялись к подклассам, поэтому в моем случае я не смог заблокировать все вставки по умолчанию в родительский класс (ActionMailer :: Preview), что было моей первоначальной целью, но блокировка для каждого класса хорошая отправная точка.
Мое приложение требует уточнения всех методов, но контроль может быть выполнен только для интересных методов, таких как уничтожение или обновление, и они могут работать для всех случаев, включая один из исходного вопроса.