はじめに
第5回は、Modelを作って遊んでみます!
Modelはデータベースと密に関係していますので、メソッドをつかってCRUDを試してみます。
前回のソースコード
前回のソースコードはこちらに格納してます。今回のだけやりたい場合はこちらからダウンロードしてください。
Userモデルを作ろう
今回作るModelは以下の通り。
ER図を描くツールはdbdiagram.ioを使ってます。Entityしか書いてないから何ともですが、便利なツールです。
Userモデルがどんなモデルかといえば、Integer型のid
をprimary keyとして、String型のname
, email
、Datetime型(年月日時分秒)のcreated_at
(作成日時), updated_at
(更新日時)を持っています。
rails generate model
モデルを作成するコマンドはrails generate model
です。Modelに必要なファイルとそのModelのデータをDBに登録するためにDB側にテーブルを作る必要があるのでマイグレーションファイルを作成してくれます。
rails generate model NAME [field:type field:type]
が型ですね。
NAME
がモデルの名前です。field
がモデルのattribute(属性)、type
が型です。
早速、ER図のモデルを作ってみましょう!
$ docker-compose up -d
$ docker-compose exec web ash
# rails generate model user name:string email:string
注目点はid
, created_at
, updated_at
のことはコマンドで定義していないところです。ここはあとで説明。
マイグレーションファイル
先ほどのコマンド実行でマイグレーションファイルが生成されています。
class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
Scaffoldの時も実は同じようにファイルができていたんですが、中身を見るのは初めてですね。
rails db:migrate
をするとRailsがこのファイルを読み込んでDBにSQLを発行してくれているんですね。
先ほどコマンドで定義したname
, email
と一緒にtimestamps
というものがあります。これがcreated_at
, updated_at
を作ってくれるやつでモデルを作成するときにRailsがデフォルトで付けてくれています。
また、create_table
はデフォルトでprimary keyとしてInteger型のid
を付けてくれます。
なので、このままマイグレーションファイルをdb:migrate
すれば先ほどのER図通りのテーブルを作成してくれます。
# rails db:migrate
Userモデルで遊んでみる
ここからは作成したUserモデルを使ってCRUDで遊んでみます。
CRUDとはデータを操作する上で基本となるCreate
(作成)、Read
(参照)、Update
(更新)、Delete
(削除)の頭文字をとったものです。Railsの場合はSQL文をコーディングするのではなく、モデルのメソッドを使うだけでCRUDができちゃうのでそれを体感しましょう!
ここからはRails consoleを使っていきます。これでRailsアプリケーションとコマンドラインで対話式にやりとりができます。
Rails consoleはそのままでもいいのですが、pry
というツールをインストールすることでRails consoleがみやすくなるのでそうします。
...
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
+ gem 'pry-rails'
end
...
gemを追加でインストールする場合は、再度Docker imageをビルドします。今立っているコンテナは古いイメージをもとに作られたコンテナなので一回落として、新しくビルドしたイメージで再度コンテナを作ってあげましょう。
# exit
$ docker-compose down
$ docker-compose build
$ docker-compose up -d
コンテナを起動できたら、コンテナの中でrails console
コマンドを使ってRails consoleを立ち上げましょう!
$ docker-compose exec web ash
# rails console
Running via Spring preloader in process 335
Loading development environment (Rails 6.0.2.1)
[1] pry(main)>
Rails console内では接頭に>
がつくので、>
がついている時はRails consoleの中でコマンドを実行しているんだなと思ってくださいね。
Create
モデルの作成の方法は大きく2種類あります。
-
new
メソッドでモデルオブジェクトを作成し、save
メソッドでデータ保存する -
create
メソッドでオブジェクト作成とデータ保存を同時に行う
Create 1: new
+save
例でtanaka@sample.com
のメアドのTaro Tanaka
さんを作ってみましょう!
> user = User.new(name: "Taro Tanaka", email: "tanaka@sample.com")
=> #<User:0x000056543a28cfa0
id: nil,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: nil,
updated_at: nil>
> user.save
(0.6ms) BEGIN
User Create (11.3ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "Taro Tanaka"], ["email", "tanaka@sample.com"], ["created_at", "2020-03-09 13:02:13.882889"], ["updated_at", "2020-03-09 13:02:13.882889"]]
(2.7ms) COMMIT
=> true
まず、User.new
で例の属性を持つUserモデルオブジェクトを作成し変数user
に代入しています。
その後、save
メソッドを実行。実行後のコンソールからDBにINSERTしているのがわかると思います。
RailsではModelのメソッドを使うことでとても簡単にSQLの操作ができるようになります。
save
メソッドはデータ作成に成功したらtrue
を失敗したらfalse
を返却するメソッドです。
また、.の形で属性の情報を取得したり設定したりできるので、以下のようなやり方でもデータを作成することができます。
yamada@sample.com
のメアドのHanako Yamada
さんを作ってみます!
> user = User.new
=> #<User:0x000056543a58a298
id: nil,
name: nil,
email: nil,
created_at: nil,
updated_at: nil>
> user.name = "Hanako Yamada"
=> "Hanako Yamada"
> user.email = "yamada@sample.com"
=> "yamada@sample.com"
> user.save
(0.8ms) BEGIN
User Create (1.6ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "Hanako Yamada"], ["email", "yamada@sample.com"], ["created_at", "2020-03-09 13:06:00.252962"], ["updated_at", "2020-03-09 13:06:00.252962"]]
(1.0ms) COMMIT
=> true
Create 2: create
create
メソッドはnew
メソッドとsave
メソッドを同時に行うメソッドっす。
john@sample.com
のメアドのJohn Smith
を作ります。突然の外国人ですが、『John Smith』は日本でいう『名無しの権兵衛』です。
> User.create(name: "John Smith", email: "john@sample.com")
(0.6ms) BEGIN
User Create (1.0ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "John Smith"], ["email", "john@sample.com"], ["created_at", "2020-03-09 13:06:23.424103"], ["updated_at", "2020-03-09 13:06:23.424103"]]
(2.2ms) COMMIT
=> #<User:0x000056543a8b3320
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>
create
は基本的にはnew
+save
なのですが、作成が成功した場合はそのモデルオブジェクト、失敗した場合はfalse
を返却するところが大きく違うポイントです。
Read
データを確認するメソッドはかなりあります。ここでは特に利用頻度が高いであろうメソッドをご紹介します。
all
all
メソッドはそのモデルの全てのレコードをオブジェクトの配列として取得します。
> User.all
User Load (17.1ms) SELECT "users".* FROM "users"
=> #<User:0x000056543a8b3320
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>
[8] pry(main)> User.all
User Load (2.8ms) SELECT "users".* FROM "users"
=> [#<User:0x000056543a958320
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>,
#<User:0x000056543a958140
id: 2,
name: "Hanako Yamada",
email: "yamada@sample.com",
created_at: Mon, 09 Mar 2020 13:06:00 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:00 JST +09:00>,
#<User:0x000056543a958050
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>]
find
find
メソッドはprimary keyの値を指定して1件のオブジェクトを取得するメソッドです。
> User.find(1)
User Load (1.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
=> #<User:0x000056543afed488
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>
マッチするレコードがない場合は、ActiveRecord::RecordNotFound Exceptionを発生させます。
> User.find(5)
User Load (3.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 5], ["LIMIT", 1]]
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=5
from /usr/local/bundle/gems/activerecord-6.0.2.1/lib/active_record/core.rb:177:in `find'
find_by
find_by
メソッドは指定したカラムの条件にマッチした1件のオブジェクトを取得するメソッドです。
> User.find_by(email: "john@sample.com")
User Load (2.8ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "john@sample.com"], ["LIMIT", 1]]
=> #<User:0x00005654375fba40
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>
マッチするレコードが存在しない場合はnilを返却します。
> User.find_by(email: "hoge@sample.com")
User Load (2.7ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "hoge@sample.com"], ["LIMIT", 1]]
=> nil
また、find_by
メソッドでは複数の条件全てにヒットする1レコードを取得する書き方もできます。
> User.find_by(name: "John Smith", email: "john@sample.com")
User Load (2.2ms) SELECT "users".* FROM "users" WHERE "users"."name" = $1 AND "users"."email" = $2 LIMIT $3 [["name", "John Smith"], ["email", "john@sample.com"], ["LIMIT", 1]]
=> #<User:0x00005654388b5b68
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>
こんな感じでユーザーを特定することができます!
where
where
メソッドはSQLのWHERE句と同様、レコードの検索条件を指定し、条件にマッチしたレコードをオブジェクトの配列として取得します。
条件はハッシュ型で書くのがわかりやすくてオススメ。
等値条件
あるカラムが特定の値と同一であるレコードを取得する場合、単にkey: value
の形で条件を指定するだけです。
> User.where(id: 1)
User Load (1.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 1]]
=> [#<User:0x0000565439591ee0
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>]
範囲条件
valueには範囲を指定することもできます。Rubyでは0 ≦ x ≦ 2
を0..2
、0 ≦ x < 2
を0...2
と表現します。
> User.where(id: 1..2)
User Load (2.6ms) SELECT "users".* FROM "users" WHERE "users"."id" BETWEEN $1 AND $2 [["id", 1], ["id", 2]]
=> [#<User:0x0000565439e6a940
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>,
#<User:0x0000565439e6a7d8
id: 2,
name: "Hanako Yamada",
email: "yamada@sample.com",
created_at: Mon, 09 Mar 2020 13:06:00 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:00 JST +09:00>]
サブセット条件
valueには配列を指定することも可能です。
> User.where(id: [1, 3])
User Load (2.8ms) SELECT "users".* FROM "users" WHERE "users"."id" IN ($1, $2) [["id", 1], ["id", 3]]
=> [#<User:0x000056543a0993b0
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>,
#<User:0x000056543a0991a8
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>]
NOT条件
where.not
メソッドを使えば、条件にヒットしないものを検索することもできます。
> User.where.not(id: 1)
User Load (2.4ms) SELECT "users".* FROM "users" WHERE "users"."id" != $1 [["id", 1]]
=> [#<User:0x000056543a2a82f0
id: 2,
name: "Hanako Yamada",
email: "yamada@sample.com",
created_at: Mon, 09 Mar 2020 13:06:00 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:00 JST +09:00>,
#<User:0x000056543a2a8228
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>]
AND条件
複数の条件にマッチするレコードを取得したい場合は、ハッシュの組み合わせを増やせばいいだけです。
> User.where(name: "Taro Tanaka", email: "tanaka@sample.com")
User Load (1.4ms) SELECT "users".* FROM "users" WHERE "users"."name" = $1 AND "users"."email" = $2 [["name", "Taro Tanaka"], ["email", "tanaka@sample.com"]]
=> [#<User:0x000056543a3f8330
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>]
OR条件
複数の条件のうち、どれか一つでも当てはまるレコードを取得したい場合はor
メソッドを使います。これはやや面倒(直感的でない)っす。
> User.where(id: 1).or(User.where(email: "john@sample.com"))
User Load (3.2ms) SELECT "users".* FROM "users" WHERE ("users"."id" = $1 OR "users"."email" = $2) [["id", 1], ["email", "john@sample.com"]]
=> [#<User:0x000056543a4c1230
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>,
#<User:0x000056543a4c1000
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>]
order
order
メソッドは並び順を指定してくれます。使い方は並び順の条件にしたいカラムを指定するだけで昇順で並び替えてくれます。
> User.order(:email)
User Load (3.5ms) SELECT "users".* FROM "users" ORDER BY "users"."email" ASC
=> [#<User:0x000056543a686728
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>,
#<User:0x000056543a686570
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>,
#<User:0x000056543a6863b8
id: 2,
name: "Hanako Yamada",
email: "yamada@sample.com",
created_at: Mon, 09 Mar 2020 13:06:00 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:00 JST +09:00>]
メアド昇順に並び変わってますね。
降順に並べる場合はdesc
を使います。(昇順も同じようにasc
を指定して表現することもできます)
> User.order(email: :desc)
User Load (2.5ms) SELECT "users".* FROM "users" ORDER BY "users"."email" DESC
=> [#<User:0x000056543a8ddda0
id: 2,
name: "Hanako Yamada",
email: "yamada@sample.com",
created_at: Mon, 09 Mar 2020 13:06:00 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:00 JST +09:00>,
#<User:0x000056543a8ddb98
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>,
#<User:0x000056543a8dda58
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>]
逆順になってる。
first
first
メソッドはprimary keyの順番で最初の1件のオブジェクトを取得するメソッドです。
> User.first
User Load (2.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<User:0x000056543aa14570
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>
結果は先ほどのfind
メソッドと同じTaro Tanakaがヒットしていますが、SQL文に違いがあることがわかります。find_by
がWHERE
で検索しているのに対して、first
はORDER
で検索してます。
また、order
メソッドと組み合わせることで、primary key以外の属性に対しても一番先頭のオブジェクトを取得することができます。こっちの方が便利な気がする。
> User.order(:email).first
User Load (2.2ms) SELECT "users".* FROM "users" ORDER BY "users"."email" ASC LIMIT $1 [["LIMIT", 1]]
=> #<User:0x000056543aab5e98
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>
last
なんとなくメソッド名からわかりますね。first
の逆、一番後ろのモデルオブジェクトを取得するメソッドです。
> User.last
User Load (1.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<User:0x000056543ab34fb8
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>
もちろんorder
と組み合わせて使うことも可能!
> User.order(:email).last
User Load (2.4ms) SELECT "users".* FROM "users" ORDER BY "users"."email" DESC LIMIT $1 [["LIMIT", 1]]
=> #<User:0x000056543abc4a78
id: 2,
name: "Hanako Yamada",
email: "yamada@sample.com",
created_at: Mon, 09 Mar 2020 13:06:00 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:00 JST +09:00>
Update
データの更新の方法も大きく2つあります。どちらの場合もまずfindやfind_byを使って単一のオブジェクトを取得します。で属性のデータを変更したあとにsave
メソッドを使って更新するか、update
メソッドで更新するかです。
属性を更新してsave
一つ目の方法は取得したオブジェクトの属性の値を変更してCreateと同じようにsave
メソッドを使うことです。
Taro Tanaka
さんのemail
をtaro@sample.com
に変更してみましょう!
> user = User.find(1)
User Load (2.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
=> #<User:0x000056543ac45060
id: 1,
name: "Taro Tanaka",
email: "tanaka@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:02:13 JST +09:00>
> user.email = "taro@sample.com"
=> "taro@sample.com"
> user.save
(0.4ms) BEGIN
User Update (3.5ms) UPDATE "users" SET "email" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["email", "taro@sample.com"], ["updated_at", "2020-03-09 13:17:32.314299"], ["id", 1]]
(1.6ms) COMMIT
=> true
> User.find(1)
User Load (4.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
=> #<User:0x000056543adb0c38
id: 1,
name: "Taro Tanaka",
email: "taro@sample.com",
created_at: Mon, 09 Mar 2020 13:02:13 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:17:32 JST +09:00>
email
変わってますね。updated_at
も自動的に更新されてます!
update
メソッドを使う
もう一つの方法はupdateメソッドを使う方法です。
今度は、Hanako Yamada
さんのemail
をhanako@sample.com
に変更してみます!
> user = User.find(2)
User Load (2.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
=> #<User:0x000056543ae6e990
id: 2,
name: "Hanako Yamada",
email: "yamada@sample.com",
created_at: Mon, 09 Mar 2020 13:06:00 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:00 JST +09:00>
> user.update(email: "hanako@sample.com")
(0.5ms) BEGIN
User Update (1.3ms) UPDATE "users" SET "email" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["email", "hanako@sample.com"], ["updated_at", "2020-03-09 13:18:46.735580"], ["id", 2]]
(0.8ms) COMMIT
=> true
> User.find(2)
User Load (4.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
=> #<User:0x000056543af50368
id: 2,
name: "Hanako Yamada",
email: "hanako@sample.com",
created_at: Mon, 09 Mar 2020 13:06:00 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:18:46 JST +09:00>
update
メソッドの場合は更新したい属性と値を括弧の中で指定します。
update
メソッドもcreate
メソッドと同じで、データ保存に成功した場合はそのモデルオブジェクトが結果として返却されていますね。
Delete
データの削除にはdestroy
メソッドを使います。今回はJohn Smith
さんが退会した、みたいな感じでデータ削除してみましょう。
> user = User.find(3)
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 3], ["LIMIT", 1]]
=> #<User:0x000056543b009660
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>
> user.destroy
(0.7ms) BEGIN
User Destroy (2.1ms) DELETE FROM "users" WHERE "users"."id" = $1 [["id", 3]]
(3.1ms) COMMIT
=> #<User:0x000056543b009660
id: 3,
name: "John Smith",
email: "john@sample.com",
created_at: Mon, 09 Mar 2020 13:06:23 JST +09:00,
updated_at: Mon, 09 Mar 2020 13:06:23 JST +09:00>
> User.find(3)
User Load (1.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 3], ["LIMIT", 1]]
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=3
from /usr/local/bundle/gems/activerecord-6.0.2.1/lib/active_record/core.rb:177:in `find'
あっけないですね。
最終的にもともとJohn Smith
さんに割り当てられていたID=3
で検索してみたところ、ActiveRecord::RecordNotFoundの例外が発生していることからJohn Smith
さんがちゃんと削除されていることがわかります。
後片付け
今日のデータをきれいにしておきましょう。今回もDBの再作成で。
> quit
quit
コマンドでRails consoleから抜け出せます。
# exit
exit
コンテナからぬけまして、
$ docker-compose down
$ docker-compose run --rm web rails db:migrate:reset
コンテナを停止して、rails db:migrate:reset
を実行っと。
まとめ
今回は、Modelの作成と基本的なモデル(データ)の操作をやってみました。
ここは僕の中でRailsの使いやすいところだなーと思っているのですが、SQLを隠してくれているんですよね。モデルのメソッドって形でデータのCRUDできるのは本当に使いやすい。
次回はモデルにバリデーションをつけていこうと思います。今のままだとname
やemail
に値がなくても保存できちゃうんですよね。
あと、Userモデルにセキュアなパスワードの属性を追加していきます。単にパスワードをカラム追加してしまったら万が一データが盗まれた時に大変な個人情報流出です。Railsではセキュアなパスワードを扱うためにhas_secure_password
メソッドが用意されているのでその使い方を紹介します。
では、次回も乞うご期待!ここまでお読みいただきありがとうございました!
Next: コーディング未経験のPO/PdMのためのRails on Dockerハンズオン vol.6 - Model validation - - Qiita
本日のソースコード
Reference
- Ruby on Rails チュートリアル:実例を使って Rails を学ぼう
- Railsタイムゾーンまとめ - Qiita
- rails-i18n/ja.yml at master · svenfuchs/rails-i18n
- もう迷わない!CSS Flexboxの使い方を徹底解説 | Web Design Trends
- 【2019年版】Google Fontsの使い方:初心者向けに解説!