2012-03-06 49 views
15

令模型Quote有属性从一个对象复制属性到另一个[price, description]滑轨:使用“属性”的方法

Invoice有属性 [price, description, priority]

令模型让invoice从模型Invoice对象具有属性{price: 10, description: 'lamp', priority: 10}

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

比方说,我想复制invoice属性到一个新的quote

quote = Quote.new(invoice.attributes) 

这就提出了一个错误priority不模型Quote existe。

如何将invoice属性复制到新的quote但只有quote可以接受的属性?

回答

19

可以select只是属性是Quote有:

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

As noted by @aceofspades(但不能和动态的解决方案),可以使用的ActiveSupport的slice还有:

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

并非所有'attribute_names'应当虽然复制。实例化时,'id','updated_at'和'created_at'应该是'nil'。 – Mischa 2014-08-22 06:54:09

+3

仅传递数组返回{},请在下面使用! Quote.new(invoice.attributes.slice(* Quote.attribute_names)) – Ajay 2015-01-02 03:58:50

+0

@ajay嗨,您的回答是非常有帮助的。我有添加多个属性的相同场景。所以我得到了一个错误“未定义的方法属性”。我该如何解决它?谢谢 – Learner 2015-03-12 11:16:34

0

直接的方法是像这样:

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

ActiveSupport的slice方法如何?

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

甚至

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

'accessible_attributes'似乎有奇怪的行为,它只返回用'attr_accessible'显式设置的属性,所以默认情况下它不包含任何属性。对我来说,这是Rails中的一个错误。 – 2012-03-06 19:50:02

+0

attr_accessible是一个非常好的主意,attribute_names在你的答案中也会起作用。 – aceofspades 2012-03-06 19:52:45

+0

我知道你*应该*但这并不意味着人们会这样做(正如周日证明的那样)。这就是说我期望它返回所有可访问的属性,而不仅仅是那些明确标记的属性。 – 2012-03-06 19:54:24