概要
このブログポストではRailsを使って本格的データを使ってみようかと思います。本格的データを使うためDBを設定して、DBテーブ路を生成する予定です。 このように生成されたDBへRailsを使ってCRUD(Create Read Update Delete)をして、Railsでデータを使う方法を理解してみようかと思います。
このブログポストはシリーズで作成されてます。詳しく内容は下記のリンクを参考してください。
- MacでRuby on Railsを始める
- Railsで作ったプロジェクトのフォルダ構造
- Ruby on Railsを使って新しウェブページを作る
- ControllerとView、Routeとのデータ交換
- RailsでDBを使う方法
ここで使ったソースコードはGithubで確認できます。
DB設定
まず、DBを使うためにはRailsへDBに関する設定をする必要があります。ここにはmysqlを設定する方法だけ紹介します。 mysqlは既にローカルにインストールされたと思って進めます。
RailsでDBの設定はconfig/database.ymlファイルが担当してます。config/database.ymlファイルを開いたら、下記のような内容が確認されます。
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: db/development.sqlite3
test:
<<: *default
database: db/test.sqlite3
production:
<<: *default
database: db/production.sqlite3
Railsは基本的sqlite3を設定しております。ここではmysqlを使う予定なので、上の設定を下記のように修正します。
default: &default
adapter: mysql2
encoding: utf8
database: study_rails
pool: 5
username: root
password:
socket: /tmp/mysql.sock
development:
<<: *default
test:
<<: *default
production:
<<: *default
上の設定でdatabase, username, passwordを自分のローカル環境に合わせて修正します。
上の設定では全ての設定をdefaultへ作成して、他の環境ではdefaultにある内容を参考するようにしました。特定な環境に必要な情報を修正したい場合は、下記のように修正することができます。
production:
<<: *default
username: root
password: XXXX
上のように修正すると、production環境時だけ、ここに書いてるusernameとpasswordを使うようになります。
DBの設定に使えるパラメーターは下記のようです。
| 名前 | 説明 |
|---|---|
| adapter | 接続するデータベースの種類(sqlite3, mysql2, postgresqlなど) |
| database | データベースの名前(sqliteはデータベースのファイル位置) |
| host | ホスト名前やIPアドレス |
| port | ポート番号 |
| pool | 確保する接続プール |
| timeout | 接続タイムアウト(ミリセコンド) |
| encoding | 使う文字コード |
| username | ユーザ名 |
| password | パスワード |
| socket | ソケット(/tmp/mysql.sock) |
mysql2
RailsでMysqlに接続するためにはmysql2と言うgemが必要です。下記のコマンドでmysql2をインストールします。
bundle add mysql2
インストールが完了されたら、下記のコマンドでデータベースを生成します。
bundle exec rake db:create
もし、下記のようなエラーメッセージが表示されて、データベースが生成されない場合、
warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
The called method `initialize' is defined here
[BUG] Segmentation fault at 0x0000000000000000
...
下記のコマンドを使ってmysql2をインストールします。
gem install mysql2 -- --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include
そして、まだ、下記のコマンドを使ってデータベースを生成します。
bundle exec rake db:create
問題なくデータベースが生成されたら下記のようなメッセージを確認することができます。
Created database 'study_rails'
Database 'study_rails' already exists
Modelを作る
データベースを作りましたので、データを保存するテーブルを作ってみましょう。Railsを使ってテーブルを作るためには、まず、Modelを生成する必要があります。
下記のコマンドを使ってModelを生成します。
# bundle exec rails generate model post
bundle exec rails g model post
このようにModelを生成すると、下記のようなファイルが生成されることが確認できます。
├── app
│ ├── models
│ │ ├── post.rb
├── db
│ ├── migrate
│ │ ├── 20200315053129_create_posts.rb
├── test
│ ├── fixtures
│ │ ├── posts.yml
│ ├── models
│ │ ├── post_test.rb
- app/models/post.rb: 実際テーブルと連結されるModel
- db/migrate/20200315053129_create_posts.rb: テーブルを生成するためのmigrationファイル
- test/fixtures/posts.yml: テストをするためDummyデータ
- test/models/post_test.rb: Modelのユニットテストをするためのファイル
テーブル生成
実際データをデータベースへ保存するためテーブルを生成してみましょう。データベースへテーブルを生成するため、Migrationファイルを修正する必要があります。
postsテーブルを生成するため、db/migrate/20200315053129_create_posts.rbファイルを開いて下記のように修正します。
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :posts do |t|
t.string :title
t.text :content
t.timestamps
end
end
end
このpostsテーブルは基本的Stringタイプのtitleと長い文字を保存するためTextタイプのcontentを持ってます。また、
bundle exec rake db:migrate
コマンドを実行するとテーブルが生成されてdb/schema.rbファイルが生成されることが確認できます。db/schema.rbファイルを開いてみると下記のような内容が確認できます。
ActiveRecord::Schema.define(version: 2020_03_15_053129) do
create_table "posts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.string "title"
t.text "content"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
また、データベースツールを使って実際テーブルが生成されたか、確認すると、下記のようにテーブルができてることが確認できます。

Migrationを使ってテーブル生成した後、下記のコマンドでテーブル生成前に戻ることができます。
bundle exec rake db:rollback
CRUD
今から上で作ったテーブルへRailsを使ってCRUD(Create Read Update Delete)をしてみます。
Create
データを生成するため、まずapp/controllers/home_controller.rbファイルを開いて、下記のように修正します。
class HomeController < ApplicationController
...
def form
end
end
ユーザから入力して貰う画面を表示するformを生成しました。当該formのActionに関するViewを作成するため、app/views/home/form.erbファイルを生成して下記のように修正します。
<a href="/list">Go back</a><br/>
<form action="/create" method="POST">
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
<label for="title">title:</label>
<input type="text" name="title" />
<label for="content">content:</label>
<input type="text" name="content" />
<input type="submit" />
</form>
ユーザがsubmitボタンを押すと、POSTで/createと言うURLへデータを送るように作りました。
そしてRouteへ当該URLを登録するため、config/routes.rbファイルを開いて下記のように修正します。
Rails.application.routes.draw do
...
get '/form', to: 'home#form'
end
そして確認のため、下記のコマンドを実行してRailsサーバを起動します。
bundle exec rails s
実行が終わったら、http://127.0.0.1:3000/formへ移動したら、下記のような画面をみることができます。

今から実際データを貰って処理する部分を作ってみましょう。app/controllers/home_controller.rbファイルを開いて下記のように修正します。
class HomeController < ApplicationController
...
def create
post = Post.new
post.title = params[:title]
post.content = params[:content]
post.save
redirect_to '/list'
end
def list
end
end
上の内容を詳しくみると、
post = Post.new: 上で作ったPOSTモデルを使って新データを生成する準備をします。post.title = params[:title]: 新く生成するPOSTデータのtitleへユーザが入力したtitleを入れます。post.content = params[:content]: 新く生成するPOSTデータのcontentへユーザが入力したcontentデータを入力します。post.save: 最後に当該データを保存することで、データベースへデータを生成(create)します。redirect_to '/list': 生成が終わったら、/listと言うURLへRedirectさせます。def list: 一旦Redirectする時、エラーが出ないようにするため、空のActionを追加します。今後、このActionへデータを表示する処理を入れる予定です。
上の内容をみるとわかりますが、createアクションはredirectさせますので、Viewが要らないです。しかし、後でデータを表示するlistアクションはViewが必要なので、app/views/home/list.erbファイルを生成しておきます。
このように追加したActionを使うためconfig/routes.rbファイルを開いて下記のように修正します。
Rails.application.routes.draw do
...
post '/create', to: 'home#create'
get '/list', to: 'home#list'
end
そしてhttp://127.0.0.1:3000/formへデータを入れてSubmitボタンを押してhttp://127.0.0.1:3000/listへ移動することが確認できます。また、データベースツールを使ってみると、下記のようにデータがうまく追加されたことが確認できます。

Read
이제 위에서 생성한 데이터를 읽어와서(Read), 화면에 표시해 보도록 합시다. app/controllers/home_controller.rb 파일을 열고 아래와 같이 수정합니다.
class HomeController < ApplicationController
...
def list
@posts = Post.all
end
end
上でPost.allを使ってPostテーブルへ保存した全てのデータを取ってきました。このように取ってきたデータをViewへ伝達するため@postsと言うインスタンス変数へ保存しました。
このように保存したデータを画面に表示するため、app/views/home/list.erbファイルを開いて下記のように修正します。
<style>
table, th, td {
border: 1px solid black;
}
</style>
<a href="/form">Create New Post</a>
<table>
<thead>
<tr>
<th>Title</th>
<th>Content</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.content %></td>
<td></td>
</tr>
<% end %>
</tbody>
</table>
ここで重要な部分は@postsのインスタンス変数を通じて持ってきたデータを下記のコードを使ってループしながら、1つづつpostの変数へ入れます。
<% @posts.each do |post| %>
...
<% end %>
このように割り当てられたpost変数からtitleとcontentを取ってきて画面に表示します。
<td><%= post.title %></td>
<td><%= post.content %></td>
このように作成して、また、http://127.0.0.1:3000/listへ接続してみると、下記のようにデータが表示されることが確認できます。

Update
今から上で生成したデータを修正(Update)する方法について説明します。app/controllers/home_controller.rbファイルを開いて下記のように修正します。
class HomeController < ApplicationController
...
def modify
@post = Post.find(params[:id])
end
end
上でmodifyはユーザへ修正するFormを提供するためのアクション(Action)です。ユーザから修正したいデータのidを受けて、受けて貰ったidで必要なデータを探して(Post.find)、探したデータをViewへ伝達するためインスタンス変数(@post)へ保存しました。
次は、追加されたデータを修正するためのFormをユーザへ提供するためapp/views/home/modify.erbファイルを生成して下記のように修正します。
<a href="/list">Go back</a><br/>
<form action="/update/<%= @post.id %>" method="POST">
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
<label for="title">title:</label>
<input type="text" name="title" value="<%= @post.title %>"/>
<label for="content">content:</label>
<input type="text" name="content" value="<%= @post.content %>" />
<input type="submit" />
</form>
データを生成するため作ったapp/views/home/form.erbと似てます。違うところはInputタグのvalueへControllerから伝達して貰ったデータを表示してます。
<input type="text" name="title" value="<%= @post.title %>%"/>
<input type="text" name="content" value="<%= @post.content %>%" />
このように生成したページを表示するためRouteを設定してみましょう。config/routes.rbファイルを開いて下記のように修正します。
Rails.application.routes.draw do
...
get '/modify/:id', to: 'home#modify'
end
データを修正するためのViewであるmodifyはURLへパラメーターを伝達する方法を使ってます。 このようにURLでidをもらって、Controllerは受けったidをデータを探して、画面へ表示する予定です。
次はmodifyページを開くためのリンクを追加するためapp/views/home/list.erbファイルを開いて下記のように修正します。
...
<table>
<thead>
...
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.content %></td>
<!-- add this line -->
<td><a href="/modify/<%= post.id %>">modify</a></td>
</tr>
<% end %>
</tbody>
</table>
このように作成して、またhttp://127.0.0.1:3000/listへ接続してみると、下記のようにデータが上手く表示されることが確認できます。

ここでmodifyリンクを押したら、下記のような画面を確認することができます。

次はデータを実際更新するアクション(Action)を作ってみましょう。上のmodifyページでsubmitボタンを押すと、/update/:idへ遷移するように作りました。
<a href="/list">Go back</a><br/>
<form action="/update/<%= @post.id %>" method="POST">
...
</form>
このリンクに該当するアクションを作るため、app/controllers/home_controller.rbを開いて下記のように修正します。
class HomeController < ApplicationController
...
def update
post = Post.find(params[:id])
post.title = params[:title]
post.content = params[:content]
post.save
redirect_to '/list'
end
end
パラメーターでもらったidで保存したデータを取ってきて、ユーザが入力したtitleとcontentデータで保存したデータを更新した後、post.saveを使ってデータを更新しました。 最後にデータを更新したら、/listページへRedirectするように設定しました。
次はこのアクションを使えるようにするためRouteへURLを追加してみましょう。config/routes.rbファイルを開いて下記のように修正します。
Rails.application.routes.draw do
...
post '/update/:id', to: 'home#update'
end
URLを通じてidパラメーターを受ける予定で、ユーザが入力したデータはPOST方式で貰う予定です。
この後、データの修正ページへ移動した後、

下記のように既存データとは違う内容を入力してみます。

そしてSubmitボタンを押すと下記のように、データが上手く更新されたことが確認できます。

Delete
次はCRUDの最後であるデータ削除(Delete)に関して説明します。データを削除するアクションを追加するためapp/controllers/home_controller.rbファイルを開いて下記のように修正します。
class HomeController < ApplicationController
...
def delete
Post.destroy(params[:id])
redirect_to '/list'
end
end
パラメーターでもらったidでPostモデルのデータを削除(Post.destroy)して/listページへRedirectするようにしました。
次はこのアクションをURLへ追加するためconfig/routes.rbファイルを開いて下記のように修正します。
Rails.application.routes.draw do
...
get '/delete/:id', to: 'home#delete'
end
そしてこのページを呼び出せるようにlistページを修正します。app/views/home/list.erbファイルを開いて下記のように修正します。
...
<table>
<thead>
...
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.content %></td>
<td>
<a href="/modify/<%= post.id %>">modify</a><br/>
<a href="/delete/<%= post.id %>">delete</a><br/>
</td>
</tr>
<% end %>
</tbody>
</table>
またhttp://127.0.0.1:3000/listへ接続したら、下記のようにdeleteリンクが追加されたことが確認できます。

そしたら、deleteリンクを押してみましょう。deleteリンクを押すと、保存されたデータが上手く削除されて、下記のようにリストページにもデータが表示されないことが確認できます。

完了
これで、Ruby on Railsでデータベースを生成してデータをCRUD(Create Read Update Delete)する方法についてみてみました。皆さんはもうRuby on Railsで基本的なウェブサービスを開発する準備ができました。
今後はウェブサービスを作って見ながら、Railsをもっと深く勉強してください。
参考
このブログポストはシリーズで作成されてます。詳しく内容は下記のリンクを参考してください。
- MacでRuby on Railsを始める
- Railsで作ったプロジェクトのフォルダ構造
- Ruby on Railsを使って新しウェブページを作る
- ControllerとView、Routeとのデータ交換
- RailsでDBを使う方法
ここで使ったソースコードはGithubで確認できます。
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Dekuが開発したアプリを使ってみてください。Dekuが開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。






