Làm cách nào để in ra nội dung của một đối tượng trong Rails để gỡ lỗi dễ dàng?


99

Tôi nghĩ rằng tôi đang cố lấy PHP tương đương với print_r()(bản in mà con người có thể đọc được); hiện tại sản lượng thô là:

ActiveRecord::Relation:0x10355d1c0

Tôi nên làm gì?


Trong trường hợp bạn không thấy nó (vì bạn đã chấp nhận một câu trả lời được đăng ngay trước câu trả lời của tôi), hãy lưu ý rằng hàm debug () hoạt động chính xác như print_r () trong PHP.
Andrew

1
Chỉ dành cho bất kỳ ai truy cập trang này sau này khi debug () đã lỗi thời, không được bao gồm dưới dạng một hàm nữa. Sẽ không hiệu quả. (Tín dụng cho stackoverflow.com/users/231309/irongaze-com vì đã chỉ ra điều này ở phía dưới trang.)
0112

Câu trả lời:


210

Nói chung, lần đầu tiên tôi thử .inspect, nếu điều đó không mang lại cho tôi những gì tôi muốn, tôi sẽ chuyển sang .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

Hy vọng rằng sẽ giúp.


5
Tôi nhận thấy rằng một số bản ghi đầu ra YAML hiển thị nhiều dữ liệu (siêu dữ liệu, có lẽ?) Hơn tôi muốn xem. Nếu tôi đang tìm kiếm phiên bản YAML của bản ghi mà tôi sẽ sử dụng y record_name.attributes. #ylà một bí danh cho to_yaml.
Tass

9

xác định phương thức to_s trong mô hình của bạn. Ví dụ

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

Sau đó, khi bạn in nó với #puts, nó sẽ hiển thị chuỗi đó với các biến đó.


Điều gì sẽ xảy ra nếu bạn không biết các biến nó chứa là gì?
cjm2671

Bạn có thể cụ thể hơn không? Bạn đang nói, điều gì sẽ xảy ra nếu một biến là một mảng hoặc hàm băm? #To_s của họ sẽ giải quyết việc đó.
Chris Ledet

Điều này không được diễn đạt chính xác. puts my_model_instancesẽ không gọi to_s. Bạn sẽ phải làm điều đó một cách rõ ràng:puts my_model_instance.to_s
thisismydesign

6

Trong Rails, bạn có thể in kết quả trong View bằng cách sử dụng gỡ lỗi '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

kết quả (trong trình duyệt)

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

Tôi đang sử dụng đá quý awesome_print

Vì vậy, bạn chỉ cần nhập:

ap @var

2
Tôi không ủng hộ việc cài đặt một viên ngọc cho một thứ quá đơn giản, nhưng tôi sử dụng Awesome Print thường xuyên.
Tass

Điều này thực sự tốt, những gì cuối cùng tôi đã làm trong mã của mình là thế này: Rails.logger.ap someObject
Aleksandar Pavić

gem install awesome_print (không cần chỉnh sửa đối với Gemfile)
Jay

4

.inspectlà những gì bạn đang tìm kiếm, IMO dễ dàng hơn nhiều .to_yaml!

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

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

2

inspectlà tuyệt vời nhưng đôi khi không đủ tốt. Ví dụ như BigDecimalin như thế này: #<BigDecimal:7ff49f5478b0,'0.1E2',9(18)>.

Để có toàn quyền kiểm soát những gì được in, bạn có thể xác định lại to_shoặc inspectcác phương pháp. Hoặc tạo một cái của riêng bạn để không làm các nhà phát triển tương lai bối rối quá nhiều.

  class Something < ApplicationRecord

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

  end

Điều này sẽ áp dụng một phương pháp (ví dụ to_s) cho tất cả các thuộc tính. Ví dụ này sẽ loại bỏ cái xấu BigDecimals.

Bạn cũng có thể xác định lại một số thuộc tính chỉ:

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

Bạn cũng có thể tạo kết hợp cả hai hoặc bằng cách nào đó thêm các liên kết.


2

pp cũng thực hiện công việc, không cần đá quý.

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

Bạn cũng có thể in hai phiên bản của một đối tượng:

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

-3

Bạn cần sử dụng debug(@var). Nó chính xác giống như "print_r".


5
Đây không phải là một điều, ít nhất là trên Ruby 1.9.x - NoMethodError: không xác định phương pháp 'debug' cho chính: Object
Irongaze.com
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.