Tengo un objeto Foo y quiero asignarle múltiples atributos a la vez, similar a assign_attributes en Rails:
class Foo attr_accessor :a, :b, :c end f = Foo.new my_hash = {a: "foo", b: "bar", c: "baz"} f.assign_attributes(my_hash)Lo anterior no funciona excepto si la clase es un modelo ActiveRecord en Rails. ¿Hay alguna forma de hacerlo en Ruby?
Puede implementar el método de asignación masiva usted mismo.
Una opción es establecer las variables de instancia correspondientes a través de instance_variable_set :
class Foo attr_accessor :a, :b, :c def assign_attributes(attrs) attrs.each_pair do |attr, value| instance_variable_set("@#{attr}", value) end end endTenga en cuenta que esto omitirá cualquier configurador personalizado. Como se dice en los documentos:
Esto puede eludir la encapsulación prevista por el autor de la clase, por lo que debe usarse con cuidado.
Otra forma es invocar dinámicamente a los setters a través public_send :
def assign_attributes(attrs) attrs.each_pair do |attr, value| public_send("#{attr}=", value) end endEsto es equivalente a configurar cada atributo individual secuencialmente. Si un setter ha sido (re)definido para incluir restricciones y controles sobre el valor que se establece, el último enfoque lo respeta.
También genera una excepción si intenta establecer atributos indefinidos: (porque el setter correspondiente no existe)
f = Foo.new f.assign_attributes(d: 'qux') #=> NoMehodError: undefined method `d=' for #<Foo:0x00007fbb76038430>Además, es posible que desee asegurarse de que el argumento pasado sea realmente un hash y tal vez genere una excepción personalizada si los atributos proporcionados no son válidos o son desconocidos.
El assign_attributes es un método de instancia de ActiveRecord
Tienes que definir tu método de assign_attributes si no usas ActiveRecord
def assign_attributes(attrs_hash) attrs_hash.each do |k, v| self.instance_variable_set("@#{k}", v) end end