web-dev-qa-db-fra.com

Comment puis-je imprimer le contenu d'un objet dans Rails pour faciliter le débogage?

Je pense que j'essaie d'obtenir l'équivalent PHP de print_r() (print lisible par l'homme); à l'heure actuelle, le résultat brut est:

ActiveRecord::Relation:0x10355d1c0

Que devrais-je faire?

83
cjm2671

En général, je commence par essayer d'abord .inspect; si cela ne me donne pas ce que je veux, je passerai à .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.

179
jerhinesmith

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 imprimer avec #puts, il affichera cette chaîne avec ces variables.

8
Chris Ledet

Dans Rails, vous pouvez imprimer le résultat dans la vue en utilisant l’aide de 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
5

J'utilise la awesome_print gem

Il suffit donc de taper:

ap @var
4
ljouglar

.inspect est ce que vous cherchez, il est beaucoup plus facile à utiliser que .to_yaml!

user = User.new
user.name = "will"
user.email = "[email protected]"

user.inspect
#<name: "will", email: "[email protected]">
2
William Hampshire

inspect c'est bien mais parfois pas assez. Par exemple. BigDecimal imprime comme ceci: #<BigDecimal:7ff49f5478b0,'0.1E2',9(18)>.

Pour avoir un contrôle total sur ce qui est imprimé, vous pouvez redéfinir les méthodes to_s ou inspect. 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

Ceci appliquera une méthode (c'est-à-dire to_s) à tous les attributs. Cet exemple vous débarrassera de la BigDecimals laide.

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 d'une manière ou d'une autre ajouter des associations.

1
thisismydesign

le pp fait le travail aussi, aucun bijou exigeant n'est exigé.

@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)
`
`
`
0
zee