attr_accessorが必要な理由と、不要な理由(Railsさんありがとう): Railsチュートリアル備忘録 - 9章


以前にも出てきたattr_accessor
あまり理解できていなかったので調べてみた

理解したこと

  • attr_accessorの役割
  • attr_accessorを意識せずにここまでこれた理由(Railsさんありがとう)

躓いたのはこれ

2行読んで続きを放棄したくなった

Userモデルには既にremember_digest属性が追加されていますが、remember_token属性はまだ追加されていません。このためuser.remember_tokenメソッドを使ってトークンにアクセスできるようにし、かつ、トークンをデータベースに保存せずに実装する必要があります。そこで、6.3で行ったパスワードの実装と同様の手法でこれを解決します。あのときは仮想のpassword属性と、データベース上にあるセキュアなpassword_digest属性の2つを使いました。仮想のpassword属性はhas_secure_passwordメソッドで自動的に作成されましたが、今回はremember_tokenのコードを自分で書く必要があります。これを実装するため、4.4.5で触れたattr_accessorを使って「仮想の」属性を作成します。(Railsチュートリアル 第6版)

少しずつ理解していく

Userモデルには既にremember_digest属性が追加されていますが、remember_token属性はまだ追加されていません。

Userモデルに既存の属性は

User.attribute_names
=> ["id", "name", "email", "created_at", "updated_at", "password_digest", "remember_digest"]

remember_token属性はない

attr_accessorとは

読み書きできる属性を定義するために用いる

attr_accessor :remember_tokenとすることで
Userクラスのオブジェクトに対してremember_token属性を定義し
user.remember_tokenと属性を参照したり
`user.remember_token = "token"と属性を代入したり
することができるようになる

以下を参考にしました
Rubyのattr_accessorって何?[和訳]

attr_accessor :nameattr_accessor :emailってやったことないよ

いままで散々user.name, user.emailを使用してきたのに
attr_accessorを意識したことはなかった

これについては
Railsから入った人へ【attr_accessor】って?

rails generate model...やmigrationの過程で
Railsが勝手に同様の処理をしてくれていたみたい

"データベースに保存せず"という点が重要だった

このためuser.remember_tokenメソッドを使ってトークンにアクセスできるようにし、かつ、トークンをデータベースに保存せずに実装する必要があります。
...
これを実装するため、4.4.5で触れたattr_accessorを使って「仮想の」属性を作成します。

remember_tokenはDBに保存しない
つまりrails generate model...やmigrationを用いずに
新たな属性を付与したいのでattr_accessorを使うと理解した

ちなみに
attr_accessor :remember_tokenが定義されていても

User.attribute_names
=> ["id", "name", "email", "created_at", "updated_at", "password_digest", "remember_digest"]

と"remember_token"はオブジェクトの属性として含まれないにもかかわらず

user.remember_token = "token"
=> "token"
>> user.remember_token
=> "token"

オブジェクトの属性のように扱うことができる
この辺が”「仮想の」属性”ということなのだろうか