0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

railsチュートリアル第6章 ユーザーオブジェクトを作成する

Posted at

###ユーザーオブジェクトを作成する
Railsコンソールを使ってデータモデルを調べてみましょう。
データベースを変更したくないので、コンソールをサンドボックスモードで起動します。

buntu:~/environment/sample_app (modeling-users) $ rails console --sandbox
Running via Spring preloader in process 13943
Loading development environment in sandbox (Rails 6.0.3)
Any modifications you make will be rolled back on exit
>> 

コンソールをサンドボックスで起動すると、そのセッションで行ったデータベースへの変更をコンソールの終了時にすべて “ロールバック”(取り消し)してくれます。

User.newで新しいユーザーオブジェクトを生成しましたが、リスト 4.17のexample_userファイルを明示的にrequireするまでこのオブジェクトにはアクセスできませんでした。
しかし、モデルを使うと状況は異なります。
Railsコンソールは起動時にRailsの環境を自動的に読み込み、その環境にはモデルも含まれます。つまり、新しいユーザーオブジェクトを作成するときに余分な作業を行わずに済む。

>> User.new
   (0.1ms)  begin transaction
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>

User.newを引数なしで呼んだ場合は、すべての属性がnilのオブジェクトを返します
オブジェクトの属性を設定するための初期化ハッシュ(hash)を引数に取るように、Userクラスの例(user_example.rb)を設計しました。

>> user = User.new(name: "Michael Hartl", email: "michael@example.com")
   (0.1ms)  begin transaction
=> #<User id: nil, name: "Michael Hartl", email: "michael@example.com", created_at: nil, updated_at: nil>

Active Recordを理解する上で、「有効性(Validity)」という概念も重要です
今はまず先ほどのuserオブジェクトが有効かどうか確認してみましょう。確認するためにはvalid?メソッドを使います

>> user.valid?
=> true

現時点ではまだデータベースにデータは格納されていません。
User.newはメモリ上でオブジェクトを作成しただけで、user.valid?という行はただオブジェクトが有効かどうかを確認しただけとなる
データベースにUserオブジェクトを保存するためには、userオブジェクトからsaveメソッドを呼び出す必要があります。

>> user.save
   (0.1ms)  SAVEPOINT active_record_1
  User Create (4.4ms)  INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "Michael Hartl"], ["email", "michael@example.com"], ["created_at", "2021-09-22 16:21:12.330460"], ["updated_at", "2021-09-22 16:21:12.330460"]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true

saveメソッドは、成功すればtrueを、失敗すればfalseを返します
Railsコンソール上ではuser.saveに対応するSQLコマンドやその結果(INSERT INTO "users"…)も表示するようになっています。
作成した時点でのユーザーオブジェクトは、id属性、マジックカラムであるcreated_at属性とupdated_at属性の値がいずれもnilであったことを思い出してください。
saveメソッドを実行した後に何が変更されたのかを確認してみましょう。

>> user
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com", created_at: "2021-09-22 16:21:12", updated_at: "2021-09-22 16:21:12">

上の結果から、idには1という値が代入され、一方でマジックカラムには現在の日時が代入されているのがわかります。
現在、作成と更新のタイムスタンプは同一ですが、更新するようになると(6.1.5)これらの値が異なっていきます。

Userモデルのインスタンスはドット記法を用いてその属性にアクセスすることができます。

>> user.name
=> "Michael Hartl"
>> user.email
=> "michael@example.com"
>> user.updated_at
=> #############

上で見たようにモデルの生成と保存を2つのステップに分けておくと何かと便利です

>> User.create
   (0.1ms)  SAVEPOINT active_record_1
  User Create (0.1ms)  INSERT INTO "users" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", "2021-09-22 16:27:20.172799"], ["updated_at", "2021-09-22 16:27:20.172799"]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 2, name: nil, email: nil, created_at: "2021-09-22 16:27:20", updated_at: "2021-09-22 16:27:20">
>> foo = User.create(name: "Foo", email: "foo@bar.com")
   (0.1ms)  SAVEPOINT active_record_1
  User Create (0.1ms)  INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "Foo"], ["email", "foo@bar.com"], ["created_at", "2021-09-22 16:30:23.066987"], ["updated_at", "2021-09-22 16:30:23.066987"]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2021-09-22 16:30:23", updated_at: "2021-09-22 16:30:23">

User.createは、trueかfalseを返す代わりに、ユーザーオブジェクト自身を返すことに注目してください。
返されたユーザーオブジェクトは変数に代入することもできます。

>> foo.destroy
   (0.1ms)  SAVEPOINT active_record_1
  User Destroy (0.1ms)  DELETE FROM "users" WHERE "users"."id" = ?  [["id", 3]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2021-09-22 16:30:23", updated_at: "2021-09-22 16:30:23">

destroyはcreateの逆です。
createと同じようにdestroyはそのオブジェクト自身を返しますが、その戻り値を使ってもう一度destroyを呼ぶことはできません

>> foo.destroy
   (0.1ms)  SAVEPOINT active_record_1
  User Destroy (0.1ms)  DELETE FROM "users" WHERE "users"."id" = ?  [["id", 3]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2021-09-22 16:30:23", updated_at: "2021-09-22 16:30:23">
>> foo
=> #<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2021-09-22 16:30:23", updated_at: "2021-09-22 16:30:23">

削除されたオブジェクトは次のようにまだメモリ上に残っています
オブジェクトが本当に削除されたかどうかをどのようにして知ればよいのでしょうか
保存して削除されていないオブジェクトの場合、どうやってデータベースからユーザーを取得するのでしょうか
これらの問いに答えるためには、Active Recordを使ってUserオブジェクトを検索する方法について学ぶ必要があります。

###演習
1.user.nameとuser.emailが、どちらもStringクラスのインスタンスであることを確認してみてください。

>> foo = user.name
=> "Michael Hartl"
>> foo.class
=> String
>> user.email.class
=> String

2.created_atとupdated_atは、どのクラスのインスタンスでしょうか?

>> user.created_at.class
=> ActiveSupport::TimeWithZone
>> user.updated_at.class
=> ActiveSupport::TimeWithZone

ActiveSupport::TimeWithZoneクラスらしい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?