Bagaimana cara mencetak konten objek di Rails untuk memudahkan debugging?


99

Saya rasa saya mencoba untuk mendapatkan PHP yang setara dengan print_r()(print human-readable); saat ini keluaran mentahnya adalah:

ActiveRecord::Relation:0x10355d1c0

Apa yang harus saya lakukan?


Jika Anda tidak melihatnya (karena Anda menerima jawaban yang diposting tepat sebelum jawaban saya), perhatikan bahwa fungsi debug () bekerja persis seperti print_r () di PHP.
Andrew

1
Hanya untuk siapa saja yang datang ke halaman ini nanti di debug () sudah usang dan tidak disertakan sebagai fungsi lagi. Tidak akan berhasil. (Penghargaan untuk stackoverflow.com/users/231309/irongaze-com karena telah menunjukkan hal ini lebih jauh ke bawah halaman.)
0112

Jawaban:


210

Saya biasanya pertama kali mencoba .inspect, jika itu tidak memberi saya apa yang saya inginkan, saya akan beralih ke .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

Semoga membantu.


5
Saya telah menemukan bahwa beberapa output data YAML menampilkan lebih banyak data (metadata, mungkin?) Daripada yang ingin saya lihat. Jika saya mencari versi YAML dari sebuah record yang akan saya gunakan y record_name.attributes. #yadalah alias untuk to_yaml.
Tass

9

tentukan metode to_s dalam model Anda. Sebagai contoh

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

Kemudian ketika Anda pergi untuk mencetaknya dengan #puts itu akan menampilkan string itu dengan variabel-variabel itu.


Bagaimana jika Anda tidak tahu apa saja variabel yang dikandungnya?
cjm2671

Bisakah Anda lebih spesifik? Apakah Anda berkata, bagaimana jika variabel adalah array atau hash? #To_s mereka akan mengurusnya.
Chris Ledet

Ini tidak diungkapkan dengan benar. puts my_model_instancetidak akan menelepon to_s. Anda harus secara eksplisit melakukan itu:puts my_model_instance.to_s
thisismydesign

6

Di Rails Anda bisa mencetak hasil di View dengan menggunakan 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

hasil (di 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

Saya menggunakan permata awesome_print

Jadi Anda hanya perlu mengetik:

ap @var

2
Saya tidak menganjurkan memasang permata untuk sesuatu yang sangat sederhana, tetapi saya menggunakan Awesome Print secara teratur.
Tass

Ini benar-benar bagus, yang akhirnya saya lakukan dalam kode saya adalah ini: Rails.logger.ap someObject
Aleksandar Pavić

gem install awesome_print (tidak perlu mengedit Gemfile)
Jay

4

.inspectadalah apa yang Anda cari, IMO jauh lebih mudah daripada .to_yaml!

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

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

2

inspectbagus tapi terkadang tidak cukup baik. Misalnya BigDecimalmencetak seperti ini: #<BigDecimal:7ff49f5478b0,'0.1E2',9(18)>.

Untuk memiliki kendali penuh atas apa yang dicetak, Anda dapat mendefinisikan ulang to_satau inspectmetode. Atau buat sendiri untuk tidak terlalu membingungkan developer di masa depan.

  class Something < ApplicationRecord

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

  end

Ini akan menerapkan metode (yaitu to_s) ke semua atribut. Contoh ini akan menyingkirkan yang jelek BigDecimals.

Anda juga dapat menentukan ulang beberapa atribut saja:

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

Anda juga dapat membuat campuran dari dua atau entah bagaimana menambahkan asosiasi.


2

pp melakukan pekerjaan itu juga, tidak ada permata yang dibutuhkan.

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

Anda juga dapat mencetak dua contoh objek:

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

-3

Anda perlu menggunakan debug(@var). Ini persis seperti "print_r".


5
Ini bukan masalah, setidaknya di Ruby 1.9.x - NoMethodError: metode `debug 'yang tidak ditentukan untuk main: Object
Irongaze.com
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.