쉬운 디버깅을 위해 Rails에서 객체의 내용을 어떻게 인쇄합니까?


99

나는 PHP에 상응하는 print_r()(인간이 읽을 수있는 인쇄); 현재 원시 출력은 다음과 같습니다.

ActiveRecord::Relation:0x10355d1c0

어떻게해야합니까?


당신이 그것을 보지 못한 경우 (당신이 내 바로 전에 게시 된 답변을 수락했기 때문에) debug () 함수 가 PHP의 print_r ()과 똑같이 작동한다는 점에 유의하십시오 .
Andrew

1
나중에 debug ()에서이 페이지를 방문하는 사람은 구식이며 더 이상 함수로 포함되지 않습니다. 작동하지 않습니다. ( 페이지 아래에서 더 자세히 지적한 점 은 stackoverflow.com/users/231309/irongaze-com에 대한 크레딧 입니다.)
0112

답변:


210

나는 일반적으로 먼저 시도 .inspect합니다 .to_yaml. 내가 원하는 것을 얻지 못하면으로 전환합니다 .

class User
  attr_accessor :name, :age
end

user = User.new
user.name = "John Smith"
user.age = 30

puts user.inspect
#=> #<User:0x423270c @name="John Smith", @age=30>
puts user.to_yaml
#=> --- !ruby/object:User
#=> age: 30
#=> name: John Smith

도움이 되었기를 바랍니다.


5
레코드의 일부 YAML 출력이 내가보고 싶은 것보다 더 많은 데이터 (아마도 메타 데이터)를 표시한다는 것을 발견했습니다. YAML 버전의 레코드를 찾고 있다면 y record_name.attributes. #y의 별칭입니다 to_yaml.
Tass

9

모델에서 to_s 메소드를 정의하십시오. 예를 들면

class Person < ActiveRecord::Base
  def to_s
    "Name:#{self.name} Age:#{self.age} Weight: #{self.weight}"
  end
end

그런 다음 #puts로 인쇄하면 해당 변수와 함께 해당 문자열이 표시됩니다.


포함 된 변수가 무엇인지 모른다면 어떻게합니까?
cjm2671 2011 년

더 자세하게 얘기해 주 시겠어요? 변수가 배열이나 해시이면 어떻게됩니까? 그들의 #to_s가 그것을 처리 할 것입니다.
Chris Ledet 2011 년

이것은 올바르게 표현되지 않았습니다. puts my_model_instance전화하지 않습니다 to_s. 다음과 같이 명시 적으로 수행해야합니다.puts my_model_instance.to_s
thisismydesign

6

Rails에서는 디버그 도우미 ActionView :: Helpers :: DebugHelper 를 사용하여 View에 결과를 인쇄 할 수 있습니다.

#app/view/controllers/post_controller.rb
def index
 @posts = Post.all
end

#app/view/posts/index.html.erb
<%= debug(@posts) %>

#start your server
rails -s

결과 (브라우저에서)

- !ruby/object:Post
  raw_attributes:
    id: 2
    title: My Second Post
    body: Welcome!  This is another example post
    published_at: '2015-10-19 23:00:43.469520'
    created_at: '2015-10-20 00:00:43.470739'
    updated_at: '2015-10-20 00:00:43.470739'
  attributes: !ruby/object:ActiveRecord::AttributeSet
    attributes: !ruby/object:ActiveRecord::LazyAttributeHash
      types: &5
        id: &2 !ruby/object:ActiveRecord::Type::Integer
          precision: 
          scale: 
          limit: 
          range: !ruby/range
            begin: -2147483648
            end: 2147483648
            excl: true
        title: &3 !ruby/object:ActiveRecord::Type::String
          precision: 
          scale: 
          limit: 
        body: &4 !ruby/object:ActiveRecord::Type::Text
          precision: 
          scale: 
          limit: 
        published_at: !ruby/object:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
          subtype: &1 !ruby/object:ActiveRecord::Type::DateTime
            precision: 
            scale: 
            limit: 
        created_at: !ruby/object:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
          subtype: *1
        updated_at: !ruby/object:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
          subtype: *1

6

awesome_print 보석을 사용하고 있습니다

따라서 다음을 입력하면됩니다.

ap @var

2
나는 그렇게 간단한 것을 위해 gem을 설치하는 것을 옹호하지는 않지만 Awesome Print를 정기적으로 사용합니다.
Tass

이것은 정말 좋습니다. 결국 제가 코드에서 한 일은 다음과 같습니다 : Rails.logger.ap someObject
Aleksandar Pavić

보석 awesome_print (Gemfile에 필요 없음 편집) 설치
제이

4

.inspect당신이 찾고있는 것입니다 .to_yaml. IMO보다 훨씬 쉽습니다 !

user = User.new
user.name = "will"
user.email = "will@example.com"

user.inspect
#<name: "will", email: "will@example.com">

2

inspect훌륭하지만 때로는 충분하지 않습니다. 예를 들어 다음 BigDecimal과 같이 인쇄 #<BigDecimal:7ff49f5478b0,'0.1E2',9(18)>됩니다..

인쇄되는 내용을 완전히 제어하려면 재정의 to_s하거나 inspect방법 을 사용할 수 있습니다. 또는 미래의 개발자를 너무 혼동하지 않도록 자신의 것을 만드십시오.

  class Something < ApplicationRecord

    def to_s
      attributes.map{ |k, v| { k => v.to_s } }.inject(:merge)
    end

  end

이렇게하면 to_s모든 속성에 메서드 (예 :)가 적용됩니다 . 이 예제는 추악한 BigDecimals.

소수의 속성 만 재정의 할 수도 있습니다.

  def to_s
    attributes.merge({ my_attribute: my_attribute.to_s })
  end

두 가지를 혼합하여 만들거나 어떻게 든 연결을 추가 할 수도 있습니다 .


2

pp도 작업을 수행하므로 gem이 필요하지 않습니다.

@a = Accrual.first ; pp @a

#<Accrual:0x007ff521e5ba50
 id: 4,
 year: 2018,
 Jan: #<BigDecimal:7ff521e58f08,'0.11E2',9(27)>,
 Feb: #<BigDecimal:7ff521e585d0,'0.88E2',9(27)>,
 Mar: #<BigDecimal:7ff521e58030,'0.0',9(27)>,
 Apr: #<BigDecimal:7ff521e53698,'0.88E2',9(27)>,
 May: #<BigDecimal:7ff521e52fb8,'0.8E1',9(27)>,
 June: #<BigDecimal:7ff521e52900,'0.8E1',9(27)>,
 July: #<BigDecimal:7ff521e51ff0,'0.8E1',9(27)>,
 Aug: #<BigDecimal:7ff521e51bb8,'0.88E2',9(27)>,
 Sep: #<BigDecimal:7ff521e512f8,'0.88E2',9(27)>,
 Oct: #<BigDecimal:7ff521e506c8,'0.0',9(27)>,
 Nov: #<BigDecimal:7ff521e43d38,'0.888E3',9(27)>,
 Dec: #<BigDecimal:7ff521e43478,'0.0',9(27)>,

개체의 두 인스턴스를 인쇄 할 수도 있습니다.

 pp( Accrual.first , Accrual.second)
`
`
`

-3

을 사용해야 debug(@var)합니다. 정확히 "print_r"과 같습니다.


5
이것은 적어도 Ruby 1.9.x에서는 문제가되지 않습니다.-NoMethodError : undefined method`debug 'for main : Object
Irongaze.com
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.