해시 할 Rails 객체
다음과 같은 객체가 생성되었습니다.
@post = Post.create(:name => 'test', :post_number => 20, :active => true)
이것이 저장되면 객체를 해시로 되돌릴 수 있기를 원합니다.
@object.to_hash
레일 안에서 어떻게 이런 일이 가능합니까?
속성 만 찾으려면 다음을 통해 속성을 얻을 수 있습니다.
@post.attributes
가장 최신 버전의 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 는 다른 객체와 관련이없는 추가 객체를 첨부하는 데 도움이됩니다. 모델 campaign에 이름 태그 가 있는 메소드를 정의하기 만하면 됩니다. 이 메소드는 필요한 것을 반환해야합니다 (예 : Tags.all)
as_json 공식 문서
You can get the attributes of a model object returned as a hash using either
@post.attributes
or
@post.as_json
as_json
allows you to include associations and their attributes as well as specify which attributes to include/exclude (see documentation). However, if you only need the attributes of the base object, benchmarking in my app with ruby 2.2.3 and rails 4.2.2 demonstrates that attributes
requires less than half as much time as 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)
There are some great suggestions here.
I think it's worth noting that you can treat an ActiveRecord model as a hash like so:
@customer = Customer.new( name: "John Jacob" )
@customer.name # => "John Jacob"
@customer[:name] # => "John Jacob"
@customer['name'] # => "John Jacob"
Therefore, instead of generating a hash of the attributes, you can use the object itself as a hash.
You could definitely use the attributes to return all attributes but you could add an instance method to Post, call it "to_hash" and have it return the data you would like in a hash. Something like
def to_hash
{ name: self.name, active: true }
end
not sure if that's what you need but try this in ruby console:
h = Hash.new
h["name"] = "test"
h["post_number"] = 20
h["active"] = true
h
obviously it will return you a hash in console. if you want to return a hash from within a method - instead of just "h" try using "return h.inspect", something similar to:
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
My solution:
Hash[ post.attributes.map{ |a| [a, post[a]] } ]
Swanand's answer is great.
if you are using FactoryGirl, you can use its build
method to generate the attribute hash without the key id
. e.g.
build(:post).attributes
Old question, but heavily referenced ... I think most people use other methods, but there is infact a to_hash
method, it has to be setup right. Generally, pluck is a better answer after rails 4 ... answering this mainly because I had to search a bunch to find this thread or anything useful & assuming others are hitting the same problem...
Note: not recommending this for everyone, but edge cases!
From the 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"},
...
] ...
참고URL : https://stackoverflow.com/questions/3872236/rails-object-to-hash
'IT' 카테고리의 다른 글
네트워크 케이블 / 커넥터의 물리적 연결 상태를 감지하는 방법은 무엇입니까? (0) | 2020.06.25 |
---|---|
JavaScript-현재 날짜에서 첫 번째 요일 가져 오기 (0) | 2020.06.25 |
onSaveInstanceState () 및 onRestoreInstanceState () (0) | 2020.06.25 |
정규식을 사용하여 bash에서 검색 및 바꾸기 (0) | 2020.06.25 |
Android : 활동이 실행 중인지 어떻게 확인합니까? (0) | 2020.06.25 |