Rails: копирование атрибутов из объекта в другой с помощью метода "атрибуты"

Пусть модель Quote имеет атрибуты [price, description]

Пусть модель Invoice имеет атрибуты [price, description, priority]

Пусть Invoice объект из Model Invoice с атрибутами {price: 10, description: 'lamp', priority: 10}

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

Скажем, я хочу скопировать атрибуты Invoice в новый Quote.

quote = Quote.new(invoice.attributes)

Это вызывает ошибку, которая priority не существует в модели Quote.

Как скопировать атрибуты Invoice в новый Quote, но могут принимать только те атрибуты, которые <<29 > ?

Ответы

Ответ 1

Вы можете select только атрибуты Quote:

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

Как отмечено @aceofspades (но не с динамическим решением), вы можете использовать ActiveSupport slice:

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

Ответ 2

Как насчет метода среза из ActiveSupport?

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

или даже

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

Ответ 3

Простым способом является что-то вроде этого:

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