Ce qui est fourni dans ActiveRecord n'affecte que certains comportements Je m'inquiète des fuites, mais je vais devoir faire de mon mieux pour fabriquer un module pour le sceller.
Placez-le autour de lib / autoload / active_record_read_only.rb
module ActiveRecordReadOnly
extend ActiveSupport::Concern
# ActiveRecord::Doit être annulé avec une erreur ReadOnlyRecord
#Il n'est pas nécessaire de le déplacer en vain, alors scellez-le
included do
before_save { self.class.raise_readonly! }
before_create { self.class.raise_readonly! }
before_update { self.class.raise_readonly! }
before_destroy { self.class.raise_readonly! }
end
#Contrôle ReadOnly de base
def readonly?
true
end
#Seal touch
#Ce n'est pas suffisant pour les raisons suivantes, mais il est écrasé pour faire correspondre la fonction de jugement avec le comportement réel.
def no_touching?
true
end
#Seal touch
# no_touching?Si vous le scellez simplement avec, cela ne causera pas d'erreur, alors scellez-le directement
def touch
self.class.raise_readonly!
end
module ClassMethods
# update_colonne et mise à jour_colonnes, etc. en lecture seule?Bloquer le traitement des spécifications de colonne sans jugement
def readonly_attributes
attribute_names
end
# readonly?Puisqu'il s'agit d'un processus unique sans jugement, il est scellé directement
def delete(_id)
raise_readonly!
end
#Puisqu'il s'agit d'une opération par lots et qu'aucune colonne n'est spécifiée, elle est scellée directement.
def delete_all
raise_readonly!
end
#Puisqu'il s'agit d'une opération par lots et qu'aucune colonne n'est spécifiée, elle est scellée directement.
def update_all(_attributes)
raise_readonly!
end
def raise_readonly!
raise ActiveRecord::ReadOnlyRecord,
"#{name}.included ActiveRecordReadOnly"
end
end
end
Incluez simplement
class User < ApplicationRecord
include ActiveRecordReadOnly
end
Peut être bloqué
[1] pry(main)> ActiveRecord::Base.logger = nil
=> nil
[2] pry(main)> User.first.destroy
ActiveRecord::ReadOnlyRecord: User.included ActiveRecordReadOnly
from /app/lib/autoload/active_record_read_only.rb:52:in `raise_readonly!'
[3] pry(main)> User.first.update(code: 'test')
ActiveRecord::ReadOnlyRecord: User.included ActiveRecordReadOnly
from /app/lib/autoload/active_record_read_only.rb:52:in `raise_readonly!'
[4] pry(main)> User.first.update_columns(code: 'test')
ActiveRecord::ActiveRecordError: code is marked as readonly
from /usr/local/bundle/gems/activerecord-6.0.0/lib/active_record/persistence.rb:947:in `verify_readonly_attribute'
[5] pry(main)> User.first.update_column(:code, 'test')
ActiveRecord::ActiveRecordError: code is marked as readonly
from /usr/local/bundle/gems/activerecord-6.0.0/lib/active_record/persistence.rb:947:in `verify_readonly_attribute'
[6] pry(main)> User.first.touch
ActiveRecord::ReadOnlyRecord: User.included ActiveRecordReadOnly
from /app/lib/autoload/active_record_read_only.rb:52:in `raise_readonly!'
[7] pry(main)> User.create(code: 'test')
ActiveRecord::ReadOnlyRecord: User.included ActiveRecordReadOnly
from /app/lib/autoload/active_record_read_only.rb:52:in `raise_readonly!'
[8] pry(main)> User.delete(1)
ActiveRecord::ReadOnlyRecord: User.included ActiveRecordReadOnly
from /app/lib/autoload/active_record_read_only.rb:52:in `raise_readonly!'
[9] pry(main)> User.delete_all
ActiveRecord::ReadOnlyRecord: User.included ActiveRecordReadOnly
from /app/lib/autoload/active_record_read_only.rb:52:in `raise_readonly!'
[10] pry(main)> User.update_all(code: 'test')
ActiveRecord::ReadOnlyRecord: User.included ActiveRecordReadOnly
from /app/lib/autoload/active_record_read_only.rb:52:in `raise_readonly!'
Lorsqu'il était appliqué au corps du modèle, il n'avait pas de sens car il peut être défini après le blocage Il est supposé qu'il sera séparé dans le modèle d'héritage pour être visualisé comme indiqué ci-dessous.
class User < ApplicationRecord
before_create -> { }
end
class ReadOnlyUser < User
include ActiveRecordReadOnly
end
Recommended Posts