如何在Rails中打印出对象的内容以便于调试?


99

我想我正在尝试获得等同于print_r()(打印出人类可读的)PHP 。目前原始输出为:

ActiveRecord::Relation:0x10355d1c0

我该怎么办?


如果您没有看到它(因为您接受了我的发布的答案),请注意debug()函数的工作原理与PHP中的print_r()完全一样。
安德鲁

1
对于以后在debug()上进入此页面的任何人来说,它已经过时了,不再作为函数提供。不行 (鸣谢stackoverflow.com/users/231309/irongaze-com,以便在页面下方进一步指出这一点。)
0112年

Answers:


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)2013年

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会解决这个问题。
克里斯·莱德

这是不正确的措词。puts my_model_instance不会打电话to_s。您将必须明确地执行以下操作:puts my_model_instance.to_s
thisismydesign '18

6

在Rails中,你可以通过调试”助手打印结果中查看的ActionView ::助手:: 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


4

.inspect是您要寻找的东西,它比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_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也能胜任,不需要宝石。

@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:main:Object的未定义方法“调试”
Irongaze.com 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.