Rails actualizar atributos sin guardar?


¿Hay una alternativa a update_attributes que no guarde el registro?

Así que podría hacer algo como:

@car = Car.new(:make => 'GMC')
#other processing
@car.update_attributes(:model => 'Sierra', :year => "2012", :looks => "Super Sexy, wanna make love to it")
#other processing
@car.save

Por cierto, sé que puedo @car.model = 'Sierra', pero quiero actualizarlos todos en una línea.

Author: user2262149, 2011-07-21

4 answers

Creo que lo que estás buscando es assign_attributes.

Es básicamente lo mismo que update_attributes pero no guarda el registro:

class User < ActiveRecord::Base
  attr_accessible :name
  attr_accessible :name, :is_admin, :as => :admin
end

user = User.new
user.assign_attributes({ :name => 'Josh', :is_admin => true }) # Raises an ActiveModel::MassAssignmentSecurity::Error
user.assign_attributes({ :name => 'Bob'})
user.name        # => "Bob"
user.is_admin?   # => false
user.new_record? # => true
 527
Author: Ajedi32,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-10 16:08:26

Puedes usar assign_attributes o attributes= (son lo mismo)

Actualizar la hoja de trucos de métodos (para Rails 4):

  • update_attributes = assign_attributes + save
  • attributes= = alias de assign_attributes
  • update = alias de update_attributes

Source:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment.rb

Otro tramposo sheet:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet

 140
Author: Yarin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-07 13:47:16

Puedes usar el método' attributes':

@car.attributes = {:model => 'Sierra', :years => '1990', :looks => 'Sexy'}

Fuente: http://api.rubyonrails.org/classes/ActiveRecord/Base.html

Attributes = (new_attributes, guard_protected_attributes = true) Le permite establecer todos los atributos a la vez pasando un hash con claves que coincidan con los nombres de los atributos (que de nuevo coincide con los nombres de las columnas).

Si guard_protected_attributes es true (el valor predeterminado), entonces los atributos sensibles se pueden proteger de esta forma de asignación masiva mediante la macro attr_protected. O puede especificar alternativamente qué atributos se pueden acceder con la macro attr_accessible. Entonces no se permitirá que todos los atributos no incluidos en eso sean asignados en masa.

class User < ActiveRecord::Base
  attr_protected :is_admin
end

user = User.new
user.attributes = { :username => 'Phusion', :is_admin => true }
user.username   # => "Phusion"
user.is_admin?  # => false

user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
user.is_admin?  # => true
 60
Author: bruno077,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-22 14:58:24

Para la asignación masiva de valores a un modelo ActiveRecord sin guardar, utilice los métodos assign_attributes o attributes=. Estos métodos están disponibles en Rails 3 y versiones posteriores. Sin embargo, hay diferencias menores y gotchas relacionadas con la versión a tener en cuenta.

Ambos métodos siguen este uso:

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }

@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }

Tenga en cuenta que ninguno de los métodos realizará validaciones o ejecutará devoluciones de llamada; las devoluciones de llamada y la validación se realizarán cuando se llame a save.

Carriles 3

attributes= difiere ligeramente desde assign_attributes en Raíles 3. attributes= comprobará que el argumento que se le pasa es un Hash, y devuelve inmediatamente si no lo es; assign_attributes no tiene tal comprobación Hash. Consulte la documentación de la API de Asignación de atributos de ActiveRecord para attributes=.

El siguiente código no válido fallará silenciosamente simplemente regresando sin establecer los atributos:

@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]

attributes= se comportará silenciosamente como si las asignaciones se hubieran realizado con éxito, cuando en realidad, no lo fueron.

Esto el código no válido generará una excepción cuando assign_attributes intente stringificar las claves hash de la matriz que contiene:

@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])

assign_attributes generará una excepción NoMethodError para stringify_keys, indicando que el primer argumento no es un Hash. La excepción en sí no es muy informativa sobre la causa real, pero el hecho de que ocurra una excepción es muy importante.

La única diferencia entre estos casos es el método utilizado para la asignación de masa: attributes= tiene éxito silenciosamente, y assign_attributes genera una excepción para informar de que se ha producido un error.

Estos ejemplos pueden parecer artificiales, y lo son hasta cierto punto, pero este tipo de error puede ocurrir fácilmente al convertir datos de una API, o incluso simplemente usar una serie de transformación de datos y olvidarse de Hash[] los resultados del .map final. Mantenga algunas líneas de código 50 arriba y 3 funciones eliminadas de su asignación de atributos, y tiene una receta para el error.

La lección con Rails 3 es esta: siempre use assign_attributes en lugar de attributes=.

Carriles 4

En Rails 4, attributes= es simplemente un alias para assign_attributes. Consulte la documentación de la API de Asignación de atributos de ActiveRecord para attributes=.

Con los carriles 4, ambos métodos pueden utilizarse indistintamente. No pasar un Hash como primer argumento resultará en una excepción muy útil: ArgumentError: When assigning attributes, you must pass a hash as an argument.

Validaciones

Si usted está pre-flighting asignaciones en preparación a un save, usted podría ser interesado en validar antes de guardar, también. Puedes usar los métodos valid? y invalid? para esto. Ambos devuelven valores booleanos. valid? devuelve true si el modelo no guardado pasa todas las validaciones o false si no lo hace. {[29] } es simplemente el inverso de valid?

valid? se puede usar así:

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?

Esto le dará la capacidad de manejar cualquier problema de validaciones antes de llamar a save.

 6
Author: Michael Gaskill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-17 15:16:01