Answers:
如果仅在寻找属性,则可以通过以下方式获取它们:
@post.attributes
.to_json
如果模型不完整,将查询数据库
joins
和一起工作select
, Person.joins(:address).select("addresses.street, persons.name").find_by_id(id).attributes
将返回 { street: "", name: "" }
as_json
,它将调用serializable_hash
,然后依次调用attributes
!因此,您的建议实际上是增加了两层复杂性attributes
,使其更加昂贵。
.as_json
会将对象序列化为ruby hash
在最新版本的Rails中(虽然无法确切地分辨出哪个),您可以使用as_json
方法:
@post = Post.first
hash = @post.as_json
puts hash.pretty_inspect
将输出:
{
:name => "test",
:post_number => 20,
:active => true
}
为了更进一步,您可以通过执行以下操作来覆盖该方法,以自定义属性的显示方式:
class Post < ActiveRecord::Base
def as_json(*args)
{
:name => "My name is '#{self.name}'",
:post_number => "Post ##{self.post_number}",
}
end
end
然后,使用与上述相同的实例,将输出:
{
:name => "My name is 'test'",
:post_number => "Post #20"
}
当然,这意味着您必须明确指定必须显示的属性。
希望这可以帮助。
编辑:
您也可以检查可哈希宝石。
@object.as_json
as_json具有根据模型关系配置复杂对象的非常灵活的方法
例
示范活动属于商店,并且有一个列表
模型列表有很多list_tasks,每个list_tasks有很多注释
我们可以得到一个json,它可以轻松地合并所有这些数据。
@campaign.as_json(
{
except: [:created_at, :updated_at],
include: {
shop: {
except: [:created_at, :updated_at, :customer_id],
include: {customer: {except: [:created_at, :updated_at]}}},
list: {
except: [:created_at, :updated_at, :observation_id],
include: {
list_tasks: {
except: [:created_at, :updated_at],
include: {comments: {except: [:created_at, :updated_at]}}
}
}
},
},
methods: :tags
})
注意方法::tags可以帮助您附加任何与其他对象没有关系的其他对象。您只需要在model campaign中定义一个带有名称标签的方法。此方法应返回您需要的任何内容(例如,Tags.all)
as_json的官方文档
to_
变体的工作方式几乎与as_
变体完全相同。我唯一不喜欢的是不保留过滤条件的顺序。它似乎按字母顺序排序。我认为这与我在环境中拥有的awesome_print宝石有关,但我认为并非如此。
您可以使用以下任一方法获取作为哈希返回的模型对象的属性
@post.attributes
要么
@post.as_json
as_json
允许您包括关联及其属性,以及指定要包括/排除的属性(请参阅文档)。但是,如果仅需要基础对象的属性,则在我的应用程序中使用ruby 2.2.3和rails 4.2.2进行基准测试表明,attributes
所需时间少于的一半as_json
。
>> p = Problem.last
Problem Load (0.5ms) SELECT "problems".* FROM "problems" ORDER BY "problems"."id" DESC LIMIT 1
=> #<Problem id: 137, enabled: true, created_at: "2016-02-19 11:20:28", updated_at: "2016-02-26 07:47:34">
>>
>> p.attributes
=> {"id"=>137, "enabled"=>true, "created_at"=>Fri, 19 Feb 2016 11:20:28 UTC +00:00, "updated_at"=>Fri, 26 Feb 2016 07:47:34 UTC +00:00}
>>
>> p.as_json
=> {"id"=>137, "enabled"=>true, "created_at"=>Fri, 19 Feb 2016 11:20:28 UTC +00:00, "updated_at"=>Fri, 26 Feb 2016 07:47:34 UTC +00:00}
>>
>> n = 1000000
>> Benchmark.bmbm do |x|
?> x.report("attributes") { n.times { p.attributes } }
?> x.report("as_json") { n.times { p.as_json } }
>> end
Rehearsal ----------------------------------------------
attributes 6.910000 0.020000 6.930000 ( 7.078699)
as_json 14.810000 0.160000 14.970000 ( 15.253316)
------------------------------------ total: 21.900000sec
user system total real
attributes 6.820000 0.010000 6.830000 ( 7.004783)
as_json 14.990000 0.050000 15.040000 ( 15.352894)
不知道这是否是您需要的,但是在ruby控制台中尝试以下操作:
h = Hash.new
h["name"] = "test"
h["post_number"] = 20
h["active"] = true
h
显然,它将在控制台中返回哈希值。如果要从方法内返回哈希值-而不是仅使用“ h”,请尝试使用“ return h.inspect”,类似于以下内容:
def wordcount(str)
h = Hash.new()
str.split.each do |key|
if h[key] == nil
h[key] = 1
else
h[key] = h[key] + 1
end
end
return h.inspect
end
老问题了,但引用很多...我想大多数人都使用其他方法,但实际上是一种to_hash
方法,必须正确设置。通常,在rails 4之后,pluck是一个更好的答案...回答这个问题主要是因为我必须搜索一堆才能找到该线程或任何有用的东西,并假设其他人遇到了同样的问题...
注意:不建议所有人使用,但建议您使用小包装!
从ruby on rails api ... http://api.rubyonrails.org/classes/ActiveRecord/Result.html ...
This class encapsulates a result returned from calling #exec_query on any database connection adapter. For example:
result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
result # => #<ActiveRecord::Result:0xdeadbeef>
...
# Get an array of hashes representing the result (column => value):
result.to_hash
# => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
{"id" => 2, "title" => "title_2", "body" => "body_2"},
...
] ...