2012-03-06 8 views
15

Let modelowych Quote mieć atrybuty [price, description]szyn: Kopiowanie atrybutów z obiektu do drugiego za pomocą „atrybuty” metoda

Let modelu Invoice mieć atrybuty [price, description, priority]

Niech invoice obiekt z modelu Invoice z atrybutami {price: 10, description: 'lamp', priority: 10}

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

Załóżmy, że chcę skopiować atrybuty invoice do nowego quote.

quote = Quote.new(invoice.attributes) 

Rodzi to błąd, który priority nie Existe w modelu Quote.

Jak skopiować atrybuty invoice do nowego quote, ale tylko te atrybuty, które może zaakceptować quote?

Odpowiedz

19

Można select tylko atrybuty, które Quote zawiera:

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

As noted by @aceofspades (ale nie z dynamicznym roztworze), można użyć ActiveSupport na slice także:

Quote.new(invoice.attributes.slice(*Quote.attribute_names)) 
+0

Nie wszyscy 'attribute_names' powinny być kopiowane chociaż. 'id',' updated_at' i 'created_at' powinny prawdopodobnie być' nil' w instancji. – Mischa

+3

Przekazanie tylko tablicy zwraca {}, użyj poniżej! Quote.new (invoice.attributes.slice (* Quote.attribute_names)) – Ajay

+0

@ajay Witam, Twoja odpowiedź jest bardzo pomocna. Mam taki sam scenariusz dla dodawania wielu atrybutów. więc mam błąd 'niezdefiniowane atrybuty metody'. Jak mogę to naprawić? Dzięki – Learner

0

Prosta droga jest coś takiego:

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

Co z metodą wycinków z ActiveSupport?

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

lub nawet

quote = Quote.new(invoice.attributes.slice(*Quote.accessible_attributes)) 
+0

'available_attributes' wydaje się mieć dziwne zachowanie, zwraca tylko atrybuty, które zostały jawnie wykonane przy pomocy' attr_accessible', więc domyślnie nie będzie zawierał żadnego z atrybutów. To dla mnie błąd w Railsach. –

+0

attr_accessible to naprawdę dobry pomysł, nazwa_atrybutu równie dobrze by działała w twojej odpowiedzi. – aceofspades

+0

Wiem, że * powinniście * ale to nie znaczy, że ludzie tak robią (jak udowodniono w niedzielę). Powiedziałem, że oczekuję, że zwróci wszystkie dostępne atrybuty, nie tylko te wyraźnie oznaczone jako takie. –

Powiązane problemy