さらなる高みへ -higher ground -

プログラミング学習の定着を狙いとしたアウトプット(独り言)をしてみるブログ

テーブルにデータを追加する-続き-【Ruby on Rails9】

ActiveRecordメソッドを使ってみる

ここでは、以下のメソッドについて確認する。

  • allメソッド
  • newメソッド
  • saveメソッド
  • createメソッド

ActiveRecordではこの他にも数多くのメソッドが定義されている。
繰り返しになるが、最終的にはテーブルから取得した情報を見た目に反映させることがゴールである。
これについては、次回確認する。

allメソッド

allメソッドはApplicationRecordを継承したモデルと結びつくテーブルのレコードを全て取得する。

[1] pry(main)> Tweet.all

以下はコンソールからallを実行した場合の例である。
ApplicationRecordを継承しているTweetクラスのクラス・メソッドのように利用する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//6b983c7a250b35d690a216bdccb5e2b0.png

また、コンソールからallを実行した場合下記の最後のように「:」と表示され次のコマンドが打てなくなる現象がある。
これはターミナルの表示領域がいっぱいになってしまうためで、「Q」 を押すと次のコマンドが打てるようになる。

[1] pry(main)> Tweet.all
Tweet Load (16.8ms)  SELECT `tweets`.* FROM `tweets`
=> [#<;Tweet:0x007fad47a6b1b0 id: 1, text: "こんにちは!", created_at: nil, updated_at: nil, name: "ken", image: nil>;,
 #<;Tweet:0x007fad42928050 id: 2, text: "また明日!", created_at: nil, updated_at: nil, name: "mami", image: nil>;,
 #<;Tweet:0x007fad47a6bae8 id: 4, text: "おはよう!", created_at: nil, updated_at: nil, name: "takumi", image: nil>;,
 #<;Tweet:0x007fad47a6ad28 id: 5, text: "プログラミング好き!", created_at: nil, updated_at: nil, name: "takumi", image: nil>;,
 #<;Tweet:0x007fad47a6b688 id: 6, text: "Ruby!", created_at: nil, updated_at: nil, name: "takumi", image: nil>;,
 #<;Tweet:0x007fad47a6a850 id: 7, text: "on!", created_at: nil, updated_at: nil, name: "takumi", image: nil>;,
 #<;Tweet:0x007fad47a6a238 id: 8, text: "Rails!", created_at: nil, updated_at: nil, name: "takumi", image: nil>;,
 #<;Tweet:0x007fad42928668 id: 9, text: "どうも!", created_at: nil, updated_at: nil, name: "takumi", image: nil>;,
 :

これでTweetsテーブルの全てのレコードをターミナル上に表示することができた。
それでは、ここで取得できたレコードが一つ一つがどのように表示されているか見ていく。

ターミナル
#<Tweet:0x0000000326db00 id: 1, name: "araki", text: "こんにちは!", image: nil, created_at: nil, updated_at: nil>

idが1のTweetのレコードを見た時、その中にはidやtextなどのカラムの値が表示されている。
これを見ることで、ApplicationRecordに定義されたメソッドを利用して取得してきたそのレコードのカラムの値などを確認することができる。
ちなみにこの「#<Tweet:~」以降に続いている「0x0000000326db00」という番号は オブジェクトidと呼ばれるもので、mysqlサーバー内でそのレコードおよびインスタンスを識別するための名前のようなものだと思っておけばよい。

newメソッド・saveメソッド

newメソッドはクラスのインスタンスを生成するメソッドである。
ApplicationRecordを継承しているモデルクラスの場合、newメソッドを実行すると関連するテーブルのカラム名がキーになったハッシュのようなものが生成される。
これをモデルクラスのインスタンスと呼ぶ。
インスタンスのそれぞれのキーに値を代入してsaveメソッドを実行するとテーブルに保存される。

ターミナル
[1] pry(main)> tweet = Tweet.new(name: "takashi", text: "Nice to meet you!")
[2] pry(main)> tweet.save

以下はコンソールからレコードを保存した場合の例である。

https://tech-master.s3.amazonaws.com/uploads/curriculums//5cb2d83511ef458789b160f3ddf185f9.png

保存されたレコードを見ると、生成されたインスタンスに引数として渡したハッシュのキーがカラム名、バリューがその値となっていることが確認できる。

createメソッド

createメソッドはレコードの作成を行うことのできるメソッドである。
newメソッドとsaveメソッドを使用して行った処理をcreateメソッドで一気に行うことができるため、単にレコードを作成する場合にはこのメソッドを使用する。

下記の例1と例2は同様の作業を行っている。

例1
ターミナル

[1] pry(main)> tweet = Tweet.new(name: "takashi", text: "Nice to meet you!")
[2] pry(main)> tweet.save

例2
ターミナル

[1] pry(main)> Tweet.create(name: "takashi", text: "Nice to meet you!")

 

SQL(エス・キュー・エル)

SQLとは、データベースに対して保存されているデータを要求する時に使用する言語の形式である。
本来ならデータベースに対しては以下のようなSQL文を使ってデータを要求しなければならないが、railsではActiveRecordのおかげで簡単にデータを要求することができる。

例1
SQL

1
SELECT  `tweets`.* FROM `tweets`
例2
ターミナル
1
[1] pry(main)> Tweet.all

上記の例1と2は同じ処理を行っている。
Railsでは例2のように記述するだけで、データベースにアクセスする際には自動的に例1のようなSQL文に変換される。

このように、ActiveRecordを使用するRailsではより直感的で短い記法でテーブルの情報を操作することができる

ターミナルで以下のコマンドを実行する

$ pwd
# 現在のディレクトリが「/home/ec2-user/environment/pictweet」であることを確認

$ rails c
# コンソールの起動

そのままコンソールで「Tweet.all」とコマンドを打ってみる。
Tweetはクラス名で、allはテーブルに保存されたデータを全て呼び出すというメソッドである。
コマンドを実行すると、呼び出されたデータは、ターミナル上に表示される。

コンソールで以下のコマンドを実行する
ターミナル
[1] pry(main)> Tweet.all
# tweetsデーブルの全てのレコードを取得する

以下のような出力結果が表示されれば、モデルとデータベースは正常に動作している。

ターミナル
[1] pry(main)> Tweet.all
Tweet Load (0.5ms)  SELECT `tweets`.* FROM `tweets`
=> [#<Tweet:0x0000000326db00 id: 1, name: "araki", text: "こんにちは!", image: nil, created_at: nil, updated_at: nil>,
 #<Tweet:0x0000000325acd0 id: 2, name: "abe", text: "ありがとう!", image: nil, created_at: nil, updated_at: nil>,
 #<Tweet:0x0000000325ab90 id: 3, name: "katahira", text: "さようなら!", image: nil, created_at: nil, updated_at: nil>

2行目に注目する。SELECT ~ と続いているのが先ほど学んだSQL文である。
SQL文も、以下の手順で実際に利用してみる。

以下の手順に従い、phpMyAdminSQL文を使用する

https://tech-master.s3.amazonaws.com/uploads/curriculums//2029caba7608a4bea0652c59196a6dfa.png

④の操作の後、以下のように表示されれば成功である。
Tweet.allで取得したレコードと同じものが取得されたことが確認できる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//8b7171fac5c74a8f3ce33feea4ffd89d.png

コンソールからレコードを作成してみる

続いて、コンソールからレコードを作成してみる。コンソールからレコードを作成するにはcreateメソッドを使用する。

コンソールで以下のコマンドを実行する
ターミナル
[2] pry(main)> Tweet.create(name: "makoto", text: "おはよう!")
# 新しいレコードの作成
「表示」をクリックし、tweetsテーブルを確認する

以下のように、tweetsテーブルに新しくレコードが追加されていればOK。

https://tech-master.s3.amazonaws.com/uploads/curriculums//cc2f423df2128630ace394f168d728b0.png

コンソールからテーブルの情報を更新する

ActiveRecordを利用して、あるテーブルのレコードの情報を更新してみる。
以下はその例になります。まずは、テーブルからレコードを一つ取り出し、変数tweetに代入する。今回はfindメソッドを使用する。

findメソッド

findメソッドは引数に指定したidにあたる作品情報を1件だけ取得する。
もし、そのidにあたる作品が存在しない場合、エラーが発生する。


ターミナル
pry(main)> tweet = Tweet.find(1)
=> <Tweet:0x00000001d98860 id: 1, name: "araki", text: "こんにちは!", image: nil, created_at: nil, updated_at: nil>
# Tweetsテーブルからidが1のレコードを取得し、tweetという変数に代入

この時、変数tweetにはApplicationRecordというクラスを継承したTweetクラスのインスタンスが代入されることになる。
ターミナルで表示されている=>以降を見ると、tweetsテーブルのカラムとそのレコードが保持しているそれぞれのカラムの値がハッシュ形式で表示されていることがわかる。

さらに、以下の例のようにすることで、このtweetの持つカラムの値を更新することができる。


ターミナル
pry(main)> tweet = Tweet.find(1)   #ツイートテーブルからidカラムの値が1のレコードをインスタンスとして取得
pry(main)> tweet.name = "abe"  #取ってきたレコードのnameというカラムを、"abe"という値に上書き
pry(main)> tweet.save   #更新したレコードを再び保存

レコードの更新

テーブルに保存されているレコードを更新するにはそのレコードをインスタンスとして取得し、カラムを指定して値を直接代入する。
上書きするだけではレコードの値は更新されないので、上書きを保存するにはインスタンスのsaveメソッドを使う。

インスタンス.カラム名 = 上書きしたい値  # 指定したカラムに値を代入
インスタンス.save                   # 更新した情報を保存する

idが1のユーザーのnameを"Shinbo"から"Abe"に更新する
user = User.find(1)    # Usersテーブルのidが1のレコードを取得
puts user.name
=> "Shinbo"            # nameカラムの値は"Shinbo"
user.name = "Abe"  # nameカラムの値を"Abe"に上書き
user.save              # 変更をデータベースに反映
puts user.name         
=> "Abe"               # nameカラムの値が"Abe"に更新された

saveメソッドを呼び出すまではインスタンスの値が更新されてはいるが、データベース上には保存されていない状態である。
データベースに更新を反映させるときはsaveメソッドを使うことを忘れないようにする。

以上の例にならい、実際にレコードを更新する。

【作業】以下の手順で、レコードを更新してみる。

  1. コンソールを起動する ターミナルからrails cコマンドでコンソールを立ち上げる。
  2. tweetsテーブルからidが1のレコードを取得し、変数に代入する コンソールで以下のように書き、実行する。
    pry(main)> tweet = Tweet.find(1)
    => <Tweet:0x00000001d98860 id: 1, name: "araki", text: "こんにちは!", image: nil, created_at: nil, updated_at: 
    # Tweetsテーブルからidが1のレコードを取得し、tweetという変数に代入
  3. 取得したレコードのtextカラムの中身を、「さようなら!」に更新する
    コンソールで以下のように書き、実行する。
    pry(main)> tweet.text = "さようなら!"
    #取ってきたレコードのtextカラムを、"さようなら"という値に上書き
  4. 上書きしたレコードを再度保存する
    コンソールで以下のように書き、実行する。

以上で、tweetsテーブルにあるidが1のレコードのtextカラムを「さようなら!」に更新することができた。
最後に、もう一度レコードを取得し、正しく上書きできているか確認する。

pry(main)> tweet = Tweet.find(1)
=> <Tweet:0x00000001d98860 id: 1, name: "araki", text: "さようなら!", image: nil, created_at: nil, updated_at: 
#正しく上書きできているかを確認

textの値が"さようなら!"になっていることがわかる。

要点チェック