답변:
속성 만 찾으려면 다음을 통해 속성을 얻을 수 있습니다.
@post.attributes
.to_json
모델이 완료되지 않은 경우 DB를 쿼리합니다
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
루비 해시로 객체를 직렬화합니다
가장 최신 버전의 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 공식 문서
to_
변형은 거의 정확히 같은 작동하는 것 같다 as_
, 변형 인용 출력을 제외하고. 내가 싫어하는 유일한 것은 필터 기준의 순서를 유지하지 않는 것입니다. 알파벳순으로 정렬 된 것 같습니다. 나는 그것이 내 환경에있는 awesome_print 보석과 관련이 있다고 생각했지만 그것이 사실이라고 생각하지 않습니다.
다음 중 하나를 사용하여 해시로 반환 된 모델 객체의 속성을 가져올 수 있습니다.
@post.attributes
또는
@post.as_json
as_json
연관 및 속성을 포함하고 포함 / 제외 할 속성을 지정할 수 있습니다 ( 문서 참조 ). 그러나 기본 객체의 속성 만 필요한 경우 루비 2.2.3 및 레일 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)
그것이 필요한지 확실하지 않지만 루비 콘솔에서 이것을 시도하십시오 :
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
Swanand의 답변은 훌륭합니다.
FactoryGirl을 사용하는 경우 해당 build
메소드를 사용 하여 키없이 속성 해시를 생성 할 수 있습니다 id
. 예 :
build(:post).attributes
오래된 질문이지만 많이 참조 ... 나는 대부분의 사람들이 다른 방법을 사용한다고 생각하지만 실제로 to_hash
방법이 있으므로 올바르게 설정해야합니다. 일반적으로 pluck은 레일 4 이후에 더 나은 대답입니다 ...이 스레드 또는 유용한 것을 찾기 위해 무리를 검색하고 다른 사람들이 동일한 문제를 겪고 있다고 가정하기 때문에 주로 대답합니다 ...
참고 : 모든 사람에게 권장하지는 않지만 가장 중요한 경우입니다!
루비 온 레일즈 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"},
...
] ...