[RUBY] LIMIT 11 when data is acquired by irb

I usually use pry, so I didn't notice it at all, but at one point I came across an event where the mystery of using irb was limit 11.

What is LIMIT 11! I couldn't help but be worried about it, so I was sloppy, but I don't know. I was really curious, so I looked it up and found out why LIMIT 11 was attached, so I wrote an article.

Confirmation of the event

Suppose you have a model like this.

class User < ApplicationRecord
  has_many :reviews
end

class Review < ApplicationRecord
  belongs_to :user
end

Let's execute the process to get the reviews that user has in irb.

irb(main):006:0> user = User.find 1
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User id: 1, name: "1234567890", created_at: "2019-12-12 05:43:52", updated_at: "2019-12-12 05:43:52">
irb(main):007:0> user.reviews
  Review Load (1.0ms)  SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`user_id` = 1 LIMIT 11
=> #<ActiveRecord::Associations::CollectionProxy [#<Review id: 1, content: "hoge", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:27:55", updated_at: "2020-06-11 05:27:55">, #<Review id: 2, content: "fuga", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:12", updated_at: "2020-06-11 05:45:12">, #<Review id: 3, content: "fuga1", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:14", updated_at: "2020-06-11 05:45:14">, #<Review id: 4, content: "fuga12", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:15", updated_at: "2020-06-11 05:45:15">, #<Review id: 5, content: "fuga123", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:17", updated_at: "2020-06-11 05:45:17">, #<Review id: 6, content: "fuga1234]", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:18", updated_at: "2020-06-11 05:45:18">, #<Review id: 7, content: "fuga12345", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:20", updated_at: "2020-06-11 05:45:20">, #<Review id: 8, content: "fuga123456", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:22", updated_at: "2020-06-11 05:45:22">, #<Review id: 9, content: "fuga1234567", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:24", updated_at: "2020-06-11 05:45:24">, #<Review id: 10, content: "fuga12345678", user_id: 1, book_id: 0, status: "draft", created_at: "2020-06-11 05:45:27", updated_at: "2020-06-11 05:45:27">, ...]>
irb(main):008:0>

It comes with LIMIT 11! Did you know where it was? Notice the query issued by ʻuser.reviews`. I will put the image of the relevant part on ↓. スクリーンショット 2020-06-11 18.03.38.png

Why isn't it LIMIT 11 even though I haven't done anything? The journey to investigate the cause begins here.

Searching for LIMIT 11 from the Rails repository

I wondered if Rails was doing something, so I honestly searched the Rails repository on Github for LIMIT 11. スクリーンショット 2020-06-11 18.16.27.png

35 items were found. It's a level that you can go visually, so if you take a quick look, ...

There was a code like that! スクリーンショット 2020-06-11 18.20.18.png

I posted the corresponding method (link to Github here)

activerecord/lib/active_record/relation.rb


def inspect
  subject = loaded? ? records : self
  entries = subject.take([limit_value, 11].compact.min).map!(&:inspect)

  entries[10] = "..." if entries.size == 11

  "#<#{self.class.name} [#{entries.join(', ')}]>"
end

I think it comes with the name of the method, but it seems that LIMIT 11 is added when using ʻinspect`. Looking at the processing, it seems that 10 pieces of data itself are returned and the 11th piece is changed to "...".

By the way, if you don't know ʻinspect`, please refer to here.

Returns a string converted from an object into a human readable format.

This method is often used when debugging.

I found that even the familiar pry will issue LIMIT 11 if you add ʻinspect`.

[12] pry(main)> user = User.find 1
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User:0x00005599999f28a0
 id: 1,
 name: "1234567890",
 created_at: Thu, 12 Dec 2019 05:43:52 UTC +00:00,
 updated_at: Thu, 12 Dec 2019 05:43:52 UTC +00:00>
[13] pry(main)> user.reviews.inspect
  Review Load (0.6ms)  SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`user_id` = 1 LIMIT 11
=> "#<ActiveRecord::Associations::CollectionProxy [#<Review id: 1, content: \"hoge\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:27:55\", updated_at: \"2020-06-11 05:27:55\">, #<Review id: 2, content: \"fuga\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:12\", updated_at: \"2020-06-11 05:45:12\">, #<Review id: 3, content: \"fuga1\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:14\", updated_at: \"2020-06-11 05:45:14\">, #<Review id: 4, content: \"fuga12\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:15\", updated_at: \"2020-06-11 05:45:15\">, #<Review id: 5, content: \"fuga123\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:17\", updated_at: \"2020-06-11 05:45:17\">, #<Review id: 6, content: \"fuga1234]\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:18\", updated_at: \"2020-06-11 05:45:18\">, #<Review id: 7, content: \"fuga12345\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:20\", updated_at: \"2020-06-11 05:45:20\">, #<Review id: 8, content: \"fuga123456\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:22\", updated_at: \"2020-06-11 05:45:22\">, #<Review id: 9, content: \"fuga1234567\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:24\", updated_at: \"2020-06-11 05:45:24\">, #<Review id: 10, content: \"fuga12345678\", user_id: 1, book_id: 0, status: \"draft\", created_at: \"2020-06-11 05:45:27\", updated_at: \"2020-06-11 05:45:27\">, ...]>"
[14] pry(main)>

Again, what ʻinspect` does is" return a string of objects converted into a human-readable format. " Certainly, even if a large amount of data is output, you will not feel like reading it visually, so you are controlling to display up to 10 pieces clearly!

So far, I've found something like that, but it's not a solution yet. Because, in irb, LIMIT 11 is attached for some reason even though ʻinspect` is not attached.

irb LIMIT 11

Next, let's focus on the output result when the command is executed with irb. The display of the 11th data when LIMIT 11 is done is converted to" ... ". This is exactly the behavior of ʻinspect` that I investigated earlier.

So when I went around with "irb" and "inspect", スクリーンショット_2020-06-11_23_05_36.png

Use Inspect for result output! When I clicked on it immediately, it was written as follows. https://docs.ruby-lang.org/ja/latest/library/irb.html#inspect_mode

You can change the result output method by setting one of the following values in conf.inspect_mode in the irb prompt and in IRB.conf [: INSPECT_MODE] in the .irbrc. false, :to_s, :raw The output result to_s is displayed. true, :p, :inspect The inspected output result is displayed. :pp, :pretty_inspect The output result is displayed as pretty_inspect. :yaml, :YAML The output result is displayed in YAML format. :marshal, :Marshal, :MARSHAL, Marshal The output result is displayed as Marshal. # Dump.

When I check the default value immediately,

irb(main):004:0> conf.inspect_mode
=> true

"Displays the inspected output result." Due to this effect, it seems that ʻinspect is always attached even if ʻinspect is not added.

I tried it with a different setting (: pretty_inspect).

irb(main):010:0> conf.inspect_mode = :pp
=> :pp
- !ruby/object:Review
  concise_attributes:
irb(main):012:0> user = User.find 1
  User Load (0.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User:0x000055fcbd833780
 id: 1,
 name: "1234567890",
 created_at: Thu, 12 Dec 2019 05:43:52 UTC +00:00,
 updated_at: Thu, 12 Dec 2019 05:43:52 UTC +00:00>
irb(main):013:0> user.reviews
  Review Load (0.8ms)  SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`user_id` = 1
=> [#<Review:0x000055fcbd87b120
  id: 1,
  content: "hoge",
  user_id: 1,
  book_id: 0,
  status: "draft",
  created_at: Thu, 11 Jun 2020 05:27:55 UTC +00:00,
  updated_at: Thu, 11 Jun 2020 05:27:55 UTC +00:00>,
 #<Review:0x000055fcbd87af68
  id: 2,
・ ・ ・ (Omitted because it is long)

It seems that LIMIT 11 is not attached.

This completes the investigation. It will be refreshing if you understand the cause properly!

Summary

As a result of this investigation, the cause of "LIMIT 11 when data is acquired by irb" is

was.

It may have been a useful result in the future to find that pretty_inspect is easier to see than ʻinspect in irb than the cause of LIMIT 11`.

Recommended Posts

LIMIT 11 when data is acquired by irb
Solution of component that saves cookie when Talend WebAPI data is acquired
Crash when deleting Realm data listed by swift: Index 1 is out of bounds
When the domain acquired by Name.com suddenly becomes unusable
When the month of the date is acquired, the January shift
Data acquisition method memo when there is HashMap in HashMap
spring-batch is automatically registered when listener is implemented by reader etc.
[App groups] What to check when UserDefaults data is inaccessible
% rails db: When creating, the LoadError caused by mimemagic is
A memorandum when you want to see the data acquired by Jena & SPARQL for each variable.