デバッグを容易にするために、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を使用して結果をビューに出力できます。

#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 gemを使用しています

したがって、次のように入力する必要があります。

ap @var

2
私はとても簡単なものにgemをインストールすることを提唱しているわけではありませんが、Awesome Printを定期的に使用しています。
Tass

これは本当に良いです、私が最終的に私のコードでやったことはこれです:Rails.logger.ap someObject
AleksandarPavićMay

gem install awesome_print(Gemfileを編集する必要はありません)
Jay

4

.inspectあなたが探しているものです、それはIMOよりもはるかに簡単なIMOです.to_yaml

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_sinspectメソッドまたはメソッドを再定義します。または、将来の開発者をあまり混乱させないように、独自のものを作成してください。

  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つのミックスを作成することができます何とか関連付けを追加します。


2

ppも仕事をします、必要な宝石は必要ありません。

@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)>,

オブジェクトの2つのインスタンスを印刷することもできます。

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

-3

を使用する必要がありますdebug(@var)。「print_r」とまったく同じです。


5
これは少なくともRuby 1.9.xでは問題ではありません-NoMethodError:main:Objectの未定義のメソッド `debug '
Irongaze.com
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.