Rails: Copiar los atributos de un objeto a otro con los “atributos” método

Deje modelo Quote tienen atributos [price, description]

Deje modelo Invoice tienen atributos [price, description, priority]

Vamos a invoice un objeto de Modelo de Invoice con atributos {price: 10, description: 'lamp', priority: 10}

invoice = {price: 10, description: 'lamp', priority: 10}

Digamos que quiero copiar invoice atributos a un nuevo quote.

quote = Quote.new(invoice.attributes)

Esto genera un error que priority no existe en el modelo Quote.

¿Cómo puedo copiar invoice atributos a un nuevo quote pero sólo los atributos que una quote puede aceptar?

OriginalEl autor Laura | 2012-03-06

3 respuestas

  1. 20

    Puede seleccionar sólo los atributos que Quote tiene:

    Quote.new(invoice.attributes.select{ |key, _| Quote.attribute_names.include? key })

    Como se nota por @aceofspades (pero no con una solución dinámica), puede utilizar ActiveSupport del sector así:

    Quote.new(invoice.attributes.slice(*Quote.attribute_names))
    No todos los attribute_names debe ser copiado sin embargo. id, updated_at y created_at probablemente debería ser nil en la creación de instancias.
    Pasando simplemente la matriz devuelve {}, usar debajo de uno! De la cita.nuevo(factura.los atributos.slice(*Cotización.attribute_names))
    Hola, Tu respuesta es realmente útil. Tengo el mismo escenario para la adición de múltiples atributos. así que me puse un error undefined method attributes. ¿Cómo puedo solucionarlo? Gracias
    Intenta depurar lo que puedes conseguir con sólo *Cotización.attribute_names, a continuación, intenta cortar atributo(s)de acuerdo a su necesidad. @Sri

    OriginalEl autor Andrew Marshall

  2. 13

    Acerca de cómo el sector método de ActiveSupport?

    quote = Quote.new(invoice.attributes.slice(:price, :description))

    o incluso

    quote = Quote.new(invoice.attributes.slice(*Quote.accessible_attributes))
    accessible_attributes parece tener comportamientos extraños, sólo devuelve los atributos que se han hecho expresamente para con attr_accessible, así que por defecto esta no contiene ninguno de los atributos. Esto, para mí, es un error en Rails, aunque.
    attr_accessible es una muy buena idea, attribute_names iba a funcionar tan bien en su respuesta.
    Yo sé que tú pero eso no significa que la gente hace (como quedó demostrado el domingo). Lo que me dijo que esperaba volver accesible a todos los atributos, no solo de aquellos que explícitamente marcados como tales.
    Hago referencia a usted, pero yo no simplemente “copiar” su respuesta—la he modificado como yo sintiera, y se utiliza un método dinámico de obtener los atributos que usted no lo hizo originalmente. Yo también soy tu upvoter.

    OriginalEl autor aceofspades

  3. 0

    La manera sencilla es algo como esto:

    source = invoice.attributes
    target = (source.keys & Quote.attribute_names).inject({}) {|target, key| target[key] = source[key]; target }
    quote = Quote.new(target)

    OriginalEl autor Simon Chiang

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *