Как мне распечатать содержимое объекта в Rails для облегчения отладки?


100

Я думаю, что пытаюсь получить PHP-эквивалент print_r()(печатать в удобочитаемом виде); в настоящее время исходный результат:

ActiveRecord::Relation:0x10355d1c0

Что я должен делать?


Если вы его не видели (поскольку вы приняли ответ, опубликованный непосредственно перед моим), обратите внимание, что функция debug () работает точно так же, как print_r () в PHP.
Эндрю

1
Просто для тех, кто позже зайдет на эту страницу, функция debug () устарела и больше не включена в качестве функции. Не получится. (Благодарим stackoverflow.com/users/231309/irongaze-com за указание на это ниже по странице.)
0112,

Ответы:


211

Обычно я сначала пробую .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

Надеюсь, это поможет.


6
Я обнаружил, что некоторые выходы записей YAML отображают больше данных (возможно, метаданных?), Чем мне хотелось бы видеть. Если я ищу YAML-версию записи, я буду использовать y record_name.attributes. #yэто псевдоним для to_yaml.
ТАСС

9

определите метод to_s в вашей модели. Например

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

Затем, когда вы пойдете напечатать его с #puts, он отобразит эту строку с этими переменными.


Что делать, если вы не знаете, какие переменные в нем содержатся?
cjm2671

Можете быть более конкретными? Вы говорите, что если переменная является массивом или хешем? Их #to_s позаботятся об этом.
Крис Ледет

Это неправильно сформулировано. puts my_model_instanceзвонить не буду to_s. Вам нужно будет сделать это явно:puts my_model_instance.to_s
thisismydesign

6

В Rails вы можете распечатать результат в представлении, используя отладочную команду 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

результаты (в браузере)

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

Я использую драгоценный камень awesome_print

Итак, вам просто нужно ввести:

ap @var

2
Я не сторонник установки гема для чего-то столь простого, но я регулярно использую Awesome Print.
ТАСС

Это действительно хорошо, в конечном итоге я сделал следующее в своем коде: Rails.logger.ap someObject
Александр Павич

gem install awesome_print (в Gemfile правки не требуются)
Джей

4

.inspectэто то, что вы ищете, это проще, чем ИМО .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: undefined метод `debug 'для main: Object
Irongaze.com
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.