references rails generate ruby-on-rails ruby-on-rails-3 activerecord

ruby-on-rails - references - rails generate model



¿Hay alguna manera fácil de hacer que un modelo Rails ActiveRecord sea de solo lectura? (7)

TL; DR para OP

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

En general

  • Para evitar crea solo: before_create { false }
  • Para evitar actualizaciones solo: before_update { false }
  • Para evitar solo destruye: before_destroy { false } # does not prevent delete

Ver también: http://guides.rubyonrails.org/active_record_callbacks.html

Quiero poder crear un registro en la base de datos pero luego evitar que Rails realice cambios a partir de ese momento. Entiendo que los cambios seguirán siendo posibles en el nivel DB.

Creo que attr_readonly hace lo que quiero en un nivel de atributo, pero no quiero tener que especificar manualmente los campos ... Prefiero tener más de un enfoque de lista blanca.

Además, sé que hay una opción: read_only para asociaciones, pero no quiero limitar la "readonlyness" del objeto a si fue obtenido a través de una asociación o no.

Finalmente, quiero poder destruir un registro así que cosas como: dependent =>: destroy funciona en las asociaciones.

Por lo tanto, para resumir: 1) permitir la creación de registros, 2) permitir la eliminación de registros, y 3) evitar el cambio de registros que se han conservado.


¿Por qué no simplemente crear un usuario en la base de datos que tiene acceso de solo lectura y que los rieles utilicen esa cuenta?

Sin embargo, si desea acceso de nivel de modelo, puede agregar lo siguiente a un modelo específico:

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


Encontré una solución más concisa, que utiliza la after_initialize llamada after_initialize :

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



Esto parece ser bastante efectivo y probablemente sea un poco exagerado, pero en mi caso, realmente quiero estar seguro de que mi aplicación nunca creará, guardará, actualizará ni destruirá ningún registro en el modelo.

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

Desde que OP me pidió poder crear y destruir, pero no guardar o actualizar, creo que esto funcionará

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

No es exactamente la excepción correcta, pero lo suficientemente cerca, creo.


Un validador personalizado puede hacer esto:

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


Al mirar ActiveRecord::Persistence , todo termina llamando a create_or_update detrás de las escenas.

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

¡Asi que! Sólo:

def readonly? !new_record? end