Comment imprimer le contenu d'un objet dans Rails pour un débogage facile?


100

Je pense que j'essaie d'obtenir l'équivalent PHP de print_r()(print human-readable); actuellement, la sortie brute est:

ActiveRecord::Relation:0x10355d1c0

Que devrais-je faire?


Si vous ne l'avez pas vu (puisque vous avez accepté une réponse publiée juste avant la mienne), notez que la fonction debug () fonctionne exactement comme print_r () en PHP.
Andrew

1
Juste pour quiconque vient sur cette page plus tard, debug () est obsolète et n'est plus inclus en tant que fonction. Ça ne marchera pas. (Crédit à stackoverflow.com/users/231309/irongaze-com pour l'avoir signalé plus bas sur la page.)
0112

Réponses:


211

J'essaie généralement d'abord .inspect, si cela ne me donne pas ce que je veux, je vais passer à .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

J'espère que cela pourra aider.


6
J'ai constaté que certaines sorties YAML d'enregistrements affichent plus de données (métadonnées, peut-être?) Que je ne souhaite en voir. Si je recherche la version YAML d'un disque, j'utiliserai y record_name.attributes. #yest un alias pour to_yaml.
Tass le

9

définissez la méthode to_s dans votre modèle. Par exemple

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

Ensuite, lorsque vous allez l'imprimer avec #puts, il affichera cette chaîne avec ces variables.


Et si vous ne savez pas quelles sont les variables qu'il contient?
cjm2671

Peux-tu être plus précis? Êtes-vous en train de dire, que se passe-t-il si une variable est un tableau ou un hachage? Leurs #to_s s'en chargeraient.
Chris Ledet

Ceci n'est pas formulé correctement. puts my_model_instancen'appelle pas to_s. Vous devrez le faire explicitement:puts my_model_instance.to_s
thisismydesign

6

Dans Rails, vous pouvez imprimer le résultat dans la vue en utilisant le débogage '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

résultats (dans le navigateur)

- !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

J'utilise la gemme awesome_print

Il vous suffit donc de taper:

ap @var

2
Je ne suis pas partisan d'installer une gemme pour quelque chose d'aussi simple, mais j'utilise régulièrement Awesome Print.
Tass le

C'est vraiment bien, ce que j'ai finalement fait dans mon code est le suivant: Rails.logger.ap someObject
Aleksandar Pavić

gem install awesome_print (aucune modification requise pour Gemfile)
Jay

4

.inspectest ce que vous recherchez, c'est beaucoup plus facile IMO que .to_yaml!

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

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

2

inspectc'est génial mais parfois pas assez. Par exemple , BigDecimalimprime comme ceci: #<BigDecimal:7ff49f5478b0,'0.1E2',9(18)>.

Pour avoir un contrôle total sur ce qui est imprimé, vous pouvez redéfinir to_sou des inspectméthodes. Ou créez le vôtre pour ne pas trop confondre les futurs développeurs.

  class Something < ApplicationRecord

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

  end

Cela appliquera une méthode (c'est to_s-à- dire ) à tous les attributs. Cet exemple permettra de se débarrasser du laid BigDecimals.

Vous pouvez également redéfinir une poignée d'attributs uniquement:

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

Vous pouvez également créer un mélange des deux ou en quelque sorte ajouter des associations.


2

pp fait le travail aussi, aucune gemme n'est requise.

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

Vous pouvez également imprimer deux instances d'un objet:

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

-3

Vous devez utiliser debug(@var). C'est exactement comme "print_r".


5
Ce n'est pas une chose, du moins sur Ruby 1.9.x - NoMethodError: méthode non définie `debug 'pour main: Object
Irongaze.com
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.