

いろんな記事をみていると、ActiveRecordの、allやwhereは、ActiveRecord::Relationのオブジェクトを返すメソッドで実際にDBにアクセスしていないって話なんですが、  
試しに自分のrails consoleで試したところ普通にDBにアクセスして取得できているんですよね。

[code]

    Recruiter.all 
    =>   Recruiter Load (1.7ms)  SELECT "recruiters".* FROM "recruiters"
    [#<Recruiter:0x000055e9db560f48
      id: "0abf31a2-e39f-472a-bb8f-fcb3016d62f8",
      last_name: "foo",
      first_name: "bar",
      email: "foo@example.com",
      created_at: Wed, 09 Feb 2022 17:57:33 JST +09:00,
      updated_at: Wed, 09 Feb 2022 17:57:33 JST +09:00,
      phone_number: "0010002000">]
    
[/code]

ログをみても、普通にSQLが発行されています。

[code]

      Recruiter Load (2.4ms)  SELECT "recruiters".* FROM "recruiters"
    
[/code]

ですが、一方でloaded?を実行するとfalseがかえるんですよね。

[code]

    Recruiter.all.loaded?
    => false
    
[/code]

自分が期待する動きは、Recruiter.allをしてもDBにアクセスせずSQLも発行しないはずなんですが、間違っていますか？


CC BY-SA 4.0
2022-02-11T22:02:41.980
86277
2022-02-12T05:04:18.253
40650
question
ruby-on-rails
rails consoleにて、モデル名.allはActiveRecord Relationを返すメソッドなのにDBアクセスしている、これは正しい？


>
> ActiveRecordの、allやwhereは、ActiveRecord::Relationのオブジェクトを返すメソッドで実際にDBにアクセスしていないって話なんですが、  
>  :  
>  自分が期待する動きは、Recruiter.allをしてもDBにアクセスせずSQLも発行しないはずなんですが、間違っていますか？

その認識が誤ってるわけではありません。`ActiveRecord::Relation`オブジェクトは実際に評価されるタイミングで初めてDBにアクセスします。

ではなぜそう見えないかというと、

  1. コンソールで`Recruiter.all`を実行
  2. `ActiveRecord::Relation`オブジェクトが帰ってくる
  3. コンソールはオブジェクトを画面に表示するため"#inspect"を呼ぶ
  4. `ActiveRecord::Relation`オブジェクトはDBにアクセスしにいく

となっているからです。一方で`Recruiter.all.loaded?`の場合は、コンソールが表示するのは`Recruiter.all.loaded?`の結果なので、DBにはアクセスしません。

`result=Recruiter.all`してから`result`を呼ぶとそのタイミングでDBにアクセスしてるのがわかると思います。


CC BY-SA 4.0
2022-02-12T05:04:18.253
86283
2022-02-12T05:04:18.253
5793
86277
answer