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
Esta publicación de blog sigue siendo válida: http://ariejan.net/2008/08/17/activerecord-read-only-models/
Básicamente puede confiar en la validación de ActiveRecord si agrega un método:
def readonly?
true
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