123

I think I'm trying to get the PHP equivalent of print_r() (print human-readable); at present the raw output is:

ActiveRecord::Relation:0x10355d1c0

What should I do?

jerhinesmith
  • 15,214
  • 17
  • 62
  • 89
cjm2671
  • 18,348
  • 31
  • 102
  • 161
  • In case you didn't see it (since you accepted an answer posted just before mine), do note that the debug() function works *exactly* like print_r() in PHP. – Andrew Jan 28 '11 at 19:36
  • 1
    Just for anyone coming to this page later on debug() is outdated an not included as a function anymore. Won't work. (Credit to http://stackoverflow.com/users/231309/irongaze-com for pointing this out further down the page.) – kingsfoil Aug 21 '14 at 19:21

9 Answers9

247

I generally first try .inspect, if that doesn't give me what I want, I'll switch to .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
starball
  • 20,030
  • 7
  • 43
  • 238
jerhinesmith
  • 15,214
  • 17
  • 62
  • 89
  • 8
    I've found that some YAML outputs of records display more data (metadata, perhaps?) than I care to see. If I'm looking for the YAML version of a record I'll use `y record_name.attributes`. `#y` is an alias for `to_yaml`. – Tass Jan 14 '16 at 15:16
9

define the to_s method in your model. For example

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

Then when you go to print it with #puts it will display that string with those variables.

Chris Ledet
  • 11,458
  • 7
  • 39
  • 47
8

I'm using the awesome_print gem

So you just have to type :

ap @var
Caleb Huitt - cjhuitt
  • 14,785
  • 3
  • 42
  • 49
ljouglar
  • 346
  • 4
  • 5
8

In Rails you can print the result in the View by using the debug' Helper 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

results (in browser)

- !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
Dorian
  • 7,749
  • 4
  • 38
  • 57
Papouche Guinslyzinho
  • 5,277
  • 14
  • 58
  • 101
6

pp does the job too, no gem requiring is required.

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

You can also print two instances of an object:

 pp( Accrual.first , Accrual.second)
`
`
`
z atef
  • 7,138
  • 3
  • 55
  • 50
3

inspect is great but sometimes not good enough. E.g. BigDecimal prints like this: #<BigDecimal:7ff49f5478b0,'0.1E2',9(18)>.

To have full control over what's printed you could redefine to_s or inspect methods. Or create your own one to not confuse future devs too much.

  class Something < ApplicationRecord

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

  end

This will apply a method (i.e. to_s) to all attributes. This example will get rid of the ugly BigDecimals.

You can also redefine a handful of attributes only:

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

You can also create a mix of the two or somehow add associations.

thisismydesign
  • 21,553
  • 9
  • 123
  • 126
3

.inspect is what you're looking for, it's way easier IMO than .to_yaml!

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

user.inspect
#<name: "will", email: "will@example.com">
Kyle Krzeski
  • 6,183
  • 6
  • 41
  • 52
2

instance.attributes prints the whole hash inside rails console.

LE-HU
  • 631
  • 5
  • 17
-4

You need to use debug(@var). It's exactly like "print_r".

Andrew
  • 42,517
  • 51
  • 181
  • 281