Wie drucke ich den Inhalt eines Objekts in Rails aus, um das Debuggen zu vereinfachen?


99

Ich denke, ich versuche, das PHP-Äquivalent von print_r()(für Menschen lesbar drucken) zu erhalten. Derzeit beträgt die Rohleistung:

ActiveRecord::Relation:0x10355d1c0

Was soll ich machen?


Falls Sie es nicht gesehen haben (da Sie eine Antwort akzeptiert haben, die kurz vor meiner veröffentlicht wurde), beachten Sie, dass die Funktion debug () genau wie print_r () in PHP funktioniert .
Andrew

1
Nur für alle, die später auf diese Seite kommen, ist debug () veraltet und nicht mehr als Funktion enthalten. Wird nicht funktionieren. ( Dank an stackoverflow.com/users/231309/irongaze-com für den Hinweis weiter unten auf der Seite.)
0112

Antworten:


210

Ich versuche im Allgemeinen zuerst .inspect, wenn das mir nicht das gibt, was ich will, wechsle ich zu .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

Hoffentlich hilft das.


5
Ich habe festgestellt, dass einige YAML-Ausgaben von Datensätzen mehr Daten anzeigen (Metadaten vielleicht?), Als ich sehen möchte. Wenn ich nach der YAML-Version eines Datensatzes suche, werde ich sie verwenden y record_name.attributes. #yist ein Alias ​​für to_yaml.
Tass

9

Definieren Sie die to_s-Methode in Ihrem Modell. Beispielsweise

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

Wenn Sie es dann mit #puts drucken, wird diese Zeichenfolge mit diesen Variablen angezeigt.


Was ist, wenn Sie nicht wissen, welche Variablen darin enthalten sind?
cjm2671

Kannst du genauer sein? Wollen Sie damit sagen, was ist, wenn eine Variable ein Array oder ein Hash ist? Ihre #to_s würden sich darum kümmern.
Chris Ledet

Dies ist nicht richtig formuliert. puts my_model_instancewird nicht anrufen to_s. Sie müssen das explizit tun:puts my_model_instance.to_s
thisismydesign

6

In Rails können Sie das Ergebnis in der Ansicht mit dem Debug 'Helper ActionView :: Helpers :: DebugHelper ' drucken

#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

Ergebnisse (im 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

6

Ich benutze das Juwel awesome_print

Sie müssen also nur Folgendes eingeben:

ap @var

2
Ich bin kein Befürworter der Installation eines Edelsteins für etwas so Einfaches, aber ich verwende regelmäßig Awesome Print.
Tass

Das ist wirklich gut, was ich schließlich in meinem Code getan habe, ist Folgendes: Rails.logger.ap someObject
Aleksandar Pavić

gem install awesome_print (keine Änderungen an Gemfile erforderlich)
Jay

4

.inspectist das, wonach du suchst, es ist IMO viel einfacher als .to_yaml!

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

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

2

inspectist toll aber manchmal nicht gut genug. ZB BigDecimalDrucke wie folgt : #<BigDecimal:7ff49f5478b0,'0.1E2',9(18)>.

Um die volle Kontrolle darüber zu haben, was gedruckt wird, können Sie to_soder inspectMethoden neu definieren . Oder erstellen Sie Ihre eigene, um zukünftige Entwickler nicht zu sehr zu verwirren.

  class Something < ApplicationRecord

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

  end

Dadurch wird eine Methode (dh to_s) auf alle Attribute angewendet. Dieses Beispiel wird das Hässliche loswerden BigDecimals.

Sie können auch nur eine Handvoll Attribute neu definieren:

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

Sie können auch eine Mischung aus beiden oder erstellen irgendwie hinzufügen Assoziationen.


2

pp erledigt den Job auch, es ist kein Edelstein erforderlich.

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

Sie können auch zwei Instanzen eines Objekts drucken:

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

-3

Sie müssen verwenden debug(@var). Es ist genau wie "print_r".


5
Dies ist keine Sache, zumindest unter Ruby 1.9.x - NoMethodError: undefinierte Methode `debug 'für main: Object
Irongaze.com
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.