根据this帖子,为了在to_json
通话期间保持属性,我们需要执行以下操作:
def attributes
super.merge('foo' => self.foo)
end
凭借初学者对Ruby的了解,我无法理解以下内容:
attribute
方法吗?super.merge
在这做什么?它将哪个hashmap附加到?答案 0 :(得分:3)
不,每个Ruby类都没有#attributes
方法。您正在使用的类可能继承自另一个类或混合在一个模块中(例如ActiveRecord::Base#attributes
)。
您定义的属性方法将覆盖任何现有的#attributes
方法。在覆盖的情况下,Ruby提供了一个#super
方法,该方法调用您要覆盖的原始方法。在这种情况下,您将调用原始#attributes
方法,该方法会返回Hash
个属性键及其值(例如{ attr1: 'a', attr2: 'b' }
)。
#merge
是一个Hash函数,您在Hash上调用原始#attributes
调用返回(例如{ attr1: 'a', attr2: 'b' }
)。 #merge
创建一个新的哈希,包含原始属性哈希以及第二个哈希中提供的键值对。
来自Hash#merge
上的Ruby 2.2文档:
merge(other_hash)→new_hash单击以切换源
merge(other_hash){| key,oldval,newval | block}→new_hash
返回一个包含other_hash和的内容的新哈希 hsh的内容。如果未指定块,则条目的值为 重复键将是other_hash的重键。否则值为 通过使用密钥调用块来确定每个重复的密钥, 它在hsh中的值及其在other_hash中的值。
h1 = { "a" => 100, "b" => 200 } h2 = { "b" => 254, "c" => 300 } h1.merge(h2) #=> {"a"=>100, "b"=>254, "c"=>300} h1.merge(h2){|key, oldval, newval| newval - oldval} #=> {"a"=>100, "b"=>54, "c"=>300} h1 #=> {"a"=>100, "b"=>200}
http://ruby-doc.org/core-2.2.0/Hash.html#method-i-merge
关于您的示例的一些注释:'foo' => self.foo
self
中指定self.foo
。仅foo
就足够了。这真的只需要分配self.foo = 'whatever'
以及您在同一范围内定义另一个foo
的情况。#attributes
正在返回的密钥类型相匹配。案例1:#attributes
返回字符串哈希 - >值,因此使用String键合并哈希值(ActiveRecord会这样做。)
{ 'attr1' => 1, 'attr2' => 'b' }.merge( { 'attr3' => '3' }
案例2:#attributes
返回符号哈希 - >值,因此使用符号键合并哈希:
{ :attr1 => 1, :attr2 => 'b' }.merge( { :attr3 => '3' }
答案 1 :(得分:2)
嗨attributes
是由ActiveRecord提供的方法。如果你单击source
,你会注意到它实际上只是公开了@attributes
的实例变量hash
(因为它可以nil
通过哈希强制执行哈希.to_hash
)。
class ActiveRecord::Base
def attributes
@attributes.to_hash
end
end
我们将调用此方法parent
,因为我们将在我们的课程中扩展其行为。这可以通过inheritance:
class Person < ActiveRecord::Base
def attributes
super.merge('foo' => self.foo)
end
end
attributes
现在调用父方法[Activerecord::Base].attributes
并向哈希添加新密钥。
此代码大致相同,应该更易于阅读。
class Person < ActiveRecord::Base
def attributes
attrs = super # eg. { name: "x", created_at: [...], [...] }
attrs[:foo] = self.foo # eg. { name: "x", foo: [...], ... }
attrs
end
end
答案 2 :(得分:0)
属性是您班级的同义词属性,变量等。并非所有类都包含属性,但通常存在数据模型来封装它们包含的属性和方法,以及修改和/或操作它们的一些行为。要使用模型的json表示来响应,通常在控制器中执行类似的操作。
respond_to :json
def tags
render :json => User.find(params[:id]).tags
end