Existe-t-il un moyen simple de créer un modèle Rails ActiveRecord en lecture seule?

Je veux pouvoir créer un enregistrement dans la firebase database, mais empêcher les modifications à partir de ce moment. Je comprends que les changements seront toujours possibles au niveau de la firebase database.

Je crois que attr_readonly fait ce que je veux sur un niveau d’atsortingbut, mais je ne veux pas avoir à spécifier manuellement des champs … Je préférerais avoir une approche de liste blanche.

En outre, je sais qu’il existe une option: read_only pour les associations, mais je ne veux pas limiter le caractère “readonlyness” de l’object à celui qui a été extrait via une association ou non.

Enfin, je veux être capable de détruire un enregistrement pour des choses comme: dependant =>: détruit les œuvres dans les associations.

Donc, pour résumer: 1) permettre la création d’enregistrements, 2) autoriser la suppression d’enregistrements, et 3) empêcher la modification des enregistrements qui ont été persistés.

En regardant ActiveRecord::Persistence , tout finit par appeler create_or_update en coulisse.

 def create_or_update raise ReadOnlyRecord if readonly? result = new_record? ? create : update result != false end 

Alors! Juste:

 def readonly? !new_record? end 

J’ai trouvé une solution plus concise, qui utilise le rappel after_initialize :

 class Post < ActiveRecord::Base after_initialize :readonly! end 

Pourquoi ne pas simplement créer un utilisateur sur la firebase database qui a un access en lecture seule, et faire en sorte que les rails utilisent ce compte.

Toutefois, si vous souhaitez accéder au niveau du modèle, vous pouvez append les éléments suivants à un modèle spécifique:

  def readonly? true end def before_destroy raise ActiveRecord::ReadOnlyRecord end 

Cet article est toujours valide: http://ariejan.net/2008/08/17/activerecord-read-only-models/

Fondamentalement, vous pouvez compter sur la validation d’ActiveRecord si vous ajoutez une méthode:

 def readonly? true end 

TL; DR pour OP

 class YourModel < ActiveRecord::Base before_save { false } # prevent create & update, allows destroy # ... end 

Généralement

  • Pour prévenir crée uniquement: before_create { false }
  • Pour empêcher les mises à jour uniquement: before_update { false }
  • Pour empêcher les destructions uniquement: before_destroy { false } # does not prevent delete

Voir aussi: http://guides.rubyonrails.org/active_record_callbacks.html

Cela semble être assez efficace et est probablement un peu exagéré, mais pour mon cas, je veux vraiment être sûr que mon application ne créera, ne sauvegardera, ne mettra à jour ou ne détruira jamais aucun enregistrement du modèle.

 module ReadOnlyModel def readonly?() true end def create_or_update() raise ActiveRecord::ReadOnlyRecord end before_create { raise ActiveRecord::ReadOnlyRecord } before_destroy { raise ActiveRecord::ReadOnlyRecord } before_save { raise ActiveRecord::ReadOnlyRecord } before_update { raise ActiveRecord::ReadOnlyRecord } end class MyModel < ActiveRecord::Base include ReadOnlyModel # ... end 

Puisque OP a demandé à pouvoir créer et détruire mais pas enregistrer ou mettre à jour, je crois que cela fonctionnera

 module SaveAndDestroyOnlyModel before_save { raise ActiveRecord::ReadOnlyRecord } before_update { raise ActiveRecord::ReadOnlyRecord } end class MyModel < ActiveRecord::Base include SaveAndDestroyOnlyModel # ... end 

Pas exactement la bonne exception, mais assez proche je pense.

Un validateur personnalisé peut le faire:

 validate :nothing_changed, unless: :new_record? # make immutable ... def nothing_changed errors.add(:base, "Record is read-only") if self.changed? end