active-hash / active_hash

A readonly ActiveRecord-esque base class that lets you use a hash, a Yaml file or a custom file as the datasource
MIT License
1.19k stars 178 forks source link

`ActiveHash::Relation` returned by `ActiveHash#where` should be reported like as an array of `ActiveHash` items selected by `where` method, in Rails Console. #285

Closed gento-ogane closed 11 months ago

gento-ogane commented 1 year ago

summary ActiveHash::Relation returned by ActiveHash#where should be reported like as an array of ActiveHash items selected by where method, in Rails Console. Because ActiveRecord::Relation returned by ActiveRecord#where is reported like as an array of ActiveRecord instances selected by where method, in Rails Console.

environment

Steps to reproduce

  1. Install active_hash gem to your rails app.
  2. Start rails cosole.
  3. Execute this code;
    class Layout < ActiveHash::Base
    self.data = [
    { id: 1, name: '1R' },
    { id: 2, name: '1K' },
    { id: 3, name: '1DK' },
    { id: 4, name: '1LDK' },
    { id: 5, name: '2K' },
    { id: 6, name: '2DK' },
    { id: 7, name: '2LDK' },
    { id: 8, name: '3K' },
    { id: 9,  name: '3DK' },
    { id: 10, name: '3LDK' },
    { id: 11, name: '4K' },
    { id: 12, name: '4DK' },
    { id: 13, name: '4LDK以上' },
    ]
    end
    Layout.where(id:[1..3])

actual result

#<ActiveHash::Relation:0x0000ffffb4b5b008
 @all_records=
  [#<Layout:0x0000ffffb4406c58 @attributes={:id=>1, :name=>"1R"}>,
   #<Layout:0x0000ffffb4406848 @attributes={:id=>2, :name=>"1K"}>,
   #<Layout:0x0000ffffb4406618 @attributes={:id=>3, :name=>"1DK"}>,
   #<Layout:0x0000ffffb44063e8 @attributes={:id=>4, :name=>"1LDK"}>,
   #<Layout:0x0000ffffb44061b8 @attributes={:id=>5, :name=>"2K"}>,
   #<Layout:0x0000ffffb4405f88 @attributes={:id=>6, :name=>"2DK"}>,
   #<Layout:0x0000ffffb4405d58 @attributes={:id=>7, :name=>"2LDK"}>,
   #<Layout:0x0000ffffb4405b28 @attributes={:id=>8, :name=>"3K"}>,
   #<Layout:0x0000ffffb44058f8 @attributes={:id=>9, :name=>"3DK"}>,
   #<Layout:0x0000ffffb44056c8 @attributes={:id=>10, :name=>"3LDK"}>,
   #<Layout:0x0000ffffb4405498 @attributes={:id=>11, :name=>"4K"}>,
   #<Layout:0x0000ffffb4405268 @attributes={:id=>12, :name=>"4DK"}>,
   #<Layout:0x0000ffffb4405010 @attributes={:id=>13, :name=>"4LDK以上"}>],
 @klass=Layout,
 @query_hash={:id=>[1..3]},
 @records_dirty=true>

expected result

[
#<Layout:0x0000ffffb4406c58 @attributes={:id=>1, :name=>"1R"}>, 
#<Layout:0x0000ffffb4406848 @attributes={:id=>2, :name=>"1K"},
#<Layout:0x0000ffffb4406618 @attributes={:id=>3, :name=>"1DK"}>
]

additional information

Now I'm trying to fix this problem. I'm researching which is the code should be modified: activehash, rails console, or irb itself.

kbrock commented 1 year ago
Model.limit(3).class
=> Vm::ActiveRecord_Relation

byebug ; pp Model.limit(3)
# byebug ; Model.limit(3)

# s
# up
# s
# up

[598, 607] in /Users/kbrock/.rubies/ruby-3.0.6/lib/ruby/3.0.0/pp.rb
   598:
   599:   # prints arguments in pretty form.
   600:   #
   601:   # pp returns argument(s).
   602:   def pp(*objs)
=> 603:     objs.each {|obj|
   604:       PP.pp(obj)
   605:     }
   606:     objs.size <= 1 ? objs.first : objs
   607:   end
(byebug) objs.class
Array

That has me confused. Not sure why this would be an array and not a relation class Sorry I don't have the bandwidth to go further.

flavorjones commented 1 year ago

What's going on here is that IRB's REPL loop runs pp to print the previous line's value.

We can customize the pp output for Active Hash associations by implementing a #pretty_print method as documented in PP Output Customization.

I'll give it a try!

flavorjones commented 1 year ago

See #288