ぞえの技術めも

Ruby on Rails勉強中

【43日目】【1日20分のRailsチュートリアル】【第6章】ユーザーオブジェクトの検索と更新

Ruby on Railsチュートリアル(第3版)

今日は「6.1.4 ユーザーオブジェクトを検索する」から。

日をまたいで学習するとRailsコンソールを起動し直さないといけないのでめんどくさいことに気付いた。

6.1.4 ユーザーオブジェクトを検索する

本編の前に準備。Railsコンソール立ち上げます。

$ rails console --sandbox

そして「6.1.3」で登録したUserは消えてしまっているので作成し直す。。

>> user = User.new(name: "Michael Hartl", email: "mhartl@example.com")
>> user.save
>> User.create(name: "A Nother", email: "another@example.org")
>> foo = User.create(name: "Foo", email: "foo@bar.com")
>> foo.destroy

これで準備は終わり。(3番目のユーザー作成要らないかも。destroyするし)

今日は検索のお話。
SQLで言えばSELECTですね。

>> User.find(1)
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2016-09-23 02:12:22", updated_at: "2016-09-23 02:12:22">

find()の引数に1を渡すことでid=1のユーザーを検索できるっぽい。

>> User.find(3)
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 3]]
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=3

id=3のユーザーは存在しない(=destroyした)のでException発生。

>> User.find_by(email: "mhartl@example.com")
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1  [["email", "mhartl@example.com"]]
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2016-09-23 02:12:22", updated_at: "2016-09-23 02:12:22">

idだけじゃなくてメールアドレス(email)などUserモデルが持ってる属性でも検索可能。

ユーザーを検索する方法は色々あるらしい。
find以外にはfirstallが一般的とのこと。

>> User.first
  User Load (0.2ms)  SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2016-09-23 02:12:22", updated_at: "2016-09-23 02:12:22">
>> User.all
  User Load (0.2ms)  SELECT "users".* FROM "users"
=> #<ActiveRecord::Relation [#<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2016-09-23 02:12:22", updated_at: "2016-09-23 02:12:22">, #<User id: 2, name: "A Nother", email: "another@example.org", created_at: "2016-09-23 02:12:37", updated_at: "2016-09-23 02:12:37">]>

allはよく使いそうだけどデータが大きくなってきたときの速度が気になる。
それは検索(find)も一緒か。

6.1.5 ユーザーオブジェクトを更新する

ユーザーのデータの更新。
saveを忘れると更新情報は保存されない。

>> user.email = "mhartl@example.net"
=> "mhartl@example.net"
>> user.save
   (0.1ms)  SAVEPOINT active_record_1
  SQL (0.2ms)  UPDATE "users" SET "email" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["email", "mhartl@example.net"], ["updated_at", "2016-09-23 02:24:35.529557"], ["id", 1]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true

更新日時も更新されてる。(作成日時はそのまま)

>> user.created_at
=> Fri, 23 Sep 2016 02:12:22 UTC +00:00
>> user.updated_at
=> Fri, 23 Sep 2016 02:24:35 UTC +00:00

update_attributesを使っても属性の更新ができるそう。

>> user.update_attributes(name: "The Dude", email: "dude@abides.org")
   (0.1ms)  SAVEPOINT active_record_1
  SQL (0.2ms)  UPDATE "users" SET "name" = ?, "email" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["name", "The Dude"], ["email", "dude@abides.org"], ["updated_at", "2016-09-23 02:28:20.027485"], ["id", 1]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true
>> user.name
=> "The Dude"
>> user.email
=> "dude@abides.org"

特定の属性のみ更新したい場合はupdate_attribute(末尾のsがない)を使う。
ぱっと見一緒やん!って思った。よく見たら上のは複数形なんだね。

>> user.update_attribute(:name, "The Dude")
   (0.1ms)  SAVEPOINT active_record_1
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true
>> user.name
=> "The Dude"

この辺りはSQL知ってたらなんとなく分かるかなぁ、といった感じ。
今日の作業時間は【23分】

次は「6.2 ユーザーを検証する」から。