ここで使用している環境
OS: Windows10
IDE: RubyMine 2020.2.3
Rails: 6.1.0
> C:\\Ruby30\\bin\\ruby.exe -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [i386-mingw32]
注意
- 一部、分かりやすくするために冗長な説明をしている箇所があります。
-
アクションを関数と呼んでいます。 - IDEにRubyMineを使用することを前提としています。
※ただし、やっていることは他エディタ/IDEでも同じなので参考にはなるかもしれません。
以上の点について、ご理解ください。
プロジェクト作成
-
New Project画面を開く -
Rails->Applicationを選択 -
Locationに好きなディレクトリ(プロジェクト名になる)を指定 -
Ruby SDKで使用するRubyを選択 -
Rails VersionでRailsバージョンを選択 -
Createをクリック
Createをクリックした後、少し処理に時間が掛かるのでしばらく待ちます。
※この解説ではディレクトリ(プロジェクト名)にRailsTestAppを使用します。
手順4で使いたいRubyが無い場合
手順5で使いたいRailsバージョンが無い場合
-
Rails VersionドロップダウンからInstall Rails Gem...を選択 - 少し待って出てきた画面の
Version to installで好きなバージョンを選択してInstall(今回は6.1.0を使用)
LoadError: cannot load such file -- rexml/document
-
Gemfileの一番下に、gem 'rexml'を追加する -
Tools->Bundler->Installをクリック -
Runをクリック
ポートを変更する(任意)
- 右上のドロップダウンから
Edit Configurations...を選択 -
Portに好きなポートを入力する
早速起動する
- 右上の再生ボタンのようなものをクリック
Listening on http://127.0.0.1:3000と表示されたら起動完了です。
エラーで起動できない場合の対処
- A server is already running. Check path/to/app/tmp/pids/server.pid.
/tmp/pids/server.pidを削除して再度起動します。
サイトにアクセスしてみる
- ブラウザで
localhost:3000にアクセスする
Routing・Model・View・Controllerの役割
Routing: リクエストから使用するコントローラを決定する
Model: データの塊(オブジェクト)
View: 見た目を制御する処理(主にHTMLなど)
Controller: 必要なModelをViewに渡す、受け取ったパラメータからModelを作成する、などの内部的な処理
例えば、全てのメモを表示する場合の全体的な順序としては
- Routingによって適切なControllerの関数を呼び出し
- ControllerでメモのModelを全て取得してViewに渡す
- Viewでそれらのデータを視覚的に表示する
といった感じです。MVCなどで調べてみると面白いかもしれません。
恐らく、書いているうちに理解できると思います。
とりあえず適当なページを作ってみる
※ここではあえてジェネレータを使用していません。
ここでは、localhost:3000/helloにアクセスしたらHomeコントローラのindex関数が呼ばれ、app/views/home/index.html.erbが表示されるようにしてみます。
コントローラ作成
Homeコントローラを作成したいため、コントローラのクラス名はHomeControllerとなります。
-
app/controllersディレクトリを右クリック -
New->Ruby File/Classをクリック -
HomeControllerと入力 -
Classを選択 Enter
これでapp/controllers/home_controller.rbが作成されました。
コントローラ編集
-
app/controllers/home_controller.rbのclass HomeControllerの行に< ApplicationControllerを追加してApplicationControllerを継承する - 空の
index関数を作成
class HomeController < ApplicationController
def index
end
end
View作成
Homeコントローラのindex関数に対応するViewを作成したいので、app/views/home/index.html.erbを作成します。
-
app/viewsディレクトリを右クリック -
New->ERB Fileをクリック -
home/index.htmlと入力 Enter
これでapp/views/home/index.html.erbが作成されました。
View編集
-
app/views/home/index.html.erbに適当な内容を書く
拡張子が.erbですが普通のHTMLです。
<h1>index.html.erb</h1>
<p>Hello, world!</p>
ルーティング編集
localhost:3000/helloへのGETリクエストを受けたらHomeコントローラのindex関数を呼ぶように設定します。
そのため、必要なルーティングはget 'hello' => 'home#index'となります。
※GETというのはHTTPメソッドの一種で、ブラウザで普通にアクセスした場合はGETになります。
-
config/routes.rbにget 'hello' => 'home#index'を追加
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get 'hello' => 'home#index'
end
ブラウザで確認
- ブラウザで
localhost:3000/helloにアクセスする
app/views/home/index.html.erbの内容が表示されます。
※Railsの再起動は不要です。
作ったページをrootに割り当てる
localhost:3000/へのGETリクエストを受けたらHomeコントローラのindex関数を呼ぶように設定します。
そのため、必要なルーティングはroot 'home#index'となります。
やっていることはget '/' => 'home#index'とほぼ同じですが、rootを使用することで、それがルートであることを明示することができます。
-
config/routes.rbにroot 'home#index'を追加
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get 'hello' => 'home#index'
root 'home#index'
end
ブラウザで確認
- ブラウザで
localhost:3000/にアクセスする
localhost:3000/でもlocalhost:3000/helloでも同じ内容が表示されていることが分かります。
※お好みでlocalhost:3000/helloへのルーティング(get 'hello' => 'home#index')を削除しても良いです。
メモを投稿できる機能を作る
モデルはMemo、コントローラはMemosController、テーブル名はmemos、メモの内容を入れるカラム名はcontentとし、以下の通りに使用出来るようにします。
| コントローラ関数名 | パス | 内容 |
|---|---|---|
| index | GET /memos | メモの一覧を表示する |
| show | GET /memos/:id | IDが:idのメモを表示する |
| new | GET /memos/new | メモを作成するためのフォームを表示する |
| create | POST /memos | メモを作成するためのフォームの送信先(ここでメモが追加される) |
さらにメモの内容は空にできなく、最大1000文字までとします。
モデル作成
「メモ」というデータの塊(オブジェクト)を扱うために、「モデル」と呼ばれるものを作成する必要があります。
ここでは、Memoというモデルを作成します。
モデル名がMemoでText型のcontentカラムを作成したいので、Generator argumentsはMemo content:textとなります。
ここでmemosというテーブル名を入力していない理由は、モデル名のMemoから自動的に推測されるためです。
-
Ctrl+Alt+GもしくはTools->Run Rails Generator...をクリック -
rails g modelを選択してEnter -
Generator argumentsにMemo content:textを入力 -
OKをクリック
※Ctrl2回->Run Anything起動->rails g modelでもOKです
マイグレーションファイル編集
テーブルを作成したり、カラムを追加するための「マイグレーション」と呼ばれる仕組みがあります。
これは、どんな名前のテーブルを作るのか、どんなカラムを作るのか、を定義するものです。
このファイルはモデルを作成するときのrails g modelコマンドによって自動的に生成されています。
ここでは、これを編集してcontentカラムをnullにできないようにします。
-
db/migrate/xxxxxxxx_create_memos.rbを開く -
t.text :contentの行にnull: falseを追加する
class CreateMemos < ActiveRecord::Migration[6.1]
def change
# memosテーブルを作成する
create_table :memos do |t|
# Text型のcontentカラムを作成する
t.text :content, null: false
# created_at(作成日時)、updated_at(更新日時)のカラムを作成する(デフォルト)
t.timestamps
end
end
end
マイグレーション実行
-
Ctrl2回->Run Anything起動->db:migrateを選択する Enter
※選択肢にdb:migrateが無い場合は、入力欄にdb:migrateと入力する。
モデル編集
contentを空に出来ないように、そして文字数を1000文字までであることを検証するようにします。
-
app/models/memo.rbを開く
class Memo < ApplicationRecord
# contentカラムのバリデーションを設定する
# presence: true - 空に出来ない
# lenght: {maximum: 1000} - 長さは最大1000文字
validates :content, presence: true, length: {maximum: 1000}
end
コントローラ作成
Homeコントローラを作成するときは分かりやすくするため手動でファイルを作成しましたが、今回はモデルの時のようにrails gコマンドを使用して生成します。
Controller nameは、基本的にモデル名の複数形にします。
Actionsにはコントローラ関数名の一覧をスペース区切りで入れます。
-
Ctrl+Alt+GもしくはTools->Run Rails Generator...をクリック -
rails g controllerを選択してEnter -
Controller nameにMemosを入力 -
Actionsにindex show new createを入力 -
OKをクリック
ルーティング編集
先ほどのrails g controllerによってルーティングが生成されています。
自動で生成されたルーティングを削除し、以下のように編集します。
ルーティングの意味が分からない場合は前述のルーティング編集を参照してください。
-
config/routes.rbを開く - 以下のように編集する
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get 'hello' => 'home#index'
resources 'memos', only: %i[index show new create]
root 'home#index'
end
resourcesは、RESTfulなルーティングをいい感じに作ってくれるやつです。
今回はindex、show、new、createしか使用しないので、onlyでシンボルの配列を指定しています。
上記のルーティングは、以下とほぼ同じです。
/memos/:idというルーティングが出てきますが、これは:idの部分に任意の値が入るという意味です。
例えば/memos/1にアクセスした場合、変数params[:id]に1が入ります。この変数はコントローラやViewで使用することができます。
ルーティングの優先順位は上からです。そのため、get 'memos/:id' => 'memos#show'より下にget 'memos/new' => 'memos#new'を配置すると、memos#showのid=newとしてルーティングされてしまいます。
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
get 'hello' => 'home#index'
# GET /memos
get 'memos' => 'memos#index'
# GET /memos/new
get 'memos/new' => 'memos#new'
# GET /memos/:id
get 'memos/:id' => 'memos#show'
# POST /memos
post 'memos' => 'memos#create'
root 'home#index'
end
コントローラ編集
コントローラでは、主に必要なモデルを取得する処理をします。
@を付けた変数をコントローラで定義することによって後述するViewで使用することができるようになります。
-
app/controllers/memos_controller.rbを以下のように編集します。
class MemosController < ApplicationController
def index
# すべてのメモを取得する
@memos = Memo.all
end
def show
# :idのメモを取得する
memo_id = params[:id]
@memo = Memo.find(memo_id)
end
def new
# 空のメモを作成する
@memo = Memo.new
end
def create
# 受け入れるパラメータを定義
# requireにはモデル名、permitにはカラム名
memo_param = params.require(:memo).permit(:content)
# メモの中身を埋めて作成
@memo = Memo.new(memo_param)
# セーブする(データベースに書き込む)
if @memo.save
# 成功した場合はメモ一覧にリダイレクト
redirect_to(@memo)
else
# エラーが発生した場合はnew(フォーム)を再表示する
render :new
end
end
end
View編集
以下のように編集します。
これはerbファイルなので、中にRubyの文を埋め込むことができます。
Rubyのifやeachなどは<% %>で囲います。
変数の中身などの結果を表示したい場合は<%= %>で囲います。
コメントを書きたい場合は<%# %>で囲います。
HTMLの<!-- -->も使用可能ですが、こちらはブラウザの「ページのソースを表示」などから見ることができます。
<%= link_to('戻る', :back) %>は、リンクを生成する関数です。
第二引数に入れている:backは前のページのパスを指しています。
link_toにmemoを入れていますが、これはメモのパス(/memos/:id)として機能します。
index
<h1>メモ一覧</h1>
<ul>
<% @memos.each do |memo| %>
<%= link_to memo do %>
<li><%= memo.content %></li>
<% end %>
<% end %>
</ul>
<%= link_to('新規作成', new_memo_path) %>
<%= link_to('戻る', :back) %>
show
<h1>メモ閲覧</h1>
<pre><%= @memo.content %></pre>
<%= link_to('戻る', :back) %>
new
<h1>メモ作成</h1>
<%# エラーがあったら表示する %>
<% if @memo.errors.any? %>
<ul>
<% @memo.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<%# modelにはコントローラで作った空のメモを指定する %>
<%= form_with(model: @memo, local: true) do |form| %>
<div class="field">
<%# メモ内容を入力するテキストエリア(labelはその説明) %>
<%= form.label :content %><br>
<%= form.text_area :content %>
</div>
<div class="actions">
<%# 送信ボタン %>
<%= form.submit %>
</div>
<% end %>
<%= link_to('戻る', :back) %>
create
app/views/memos/create.html.erbは使用しないため削除する。
-
create.html.erbファイルを右クリック -
Deleteをクリック -
OKをクリック
※これはお好みの方法でOK
動作を確認する
ブラウザでlocalhost:3000/memosにアクセスして、正常に動作するか確認します。
日本語に対応させる
デフォルトでは、このようにメッセージやボタンなどが英語になっています。

rails-i18ngemを入れる
-
Gemfileの一番下に、gem 'rails-i18n'を追加する -
Tools->Bundler->Installをクリック -
Runをクリック
日本語に設定する
-
config/application.rbを以下のように書き換える。
require_relative "boot"
require "rails/all"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module RailsTestApp
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.1
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files
# in config/environments, which are processed later.
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
# タイムゾーンを日本に設定
config.time_zone = 'Tokyo'
config.active_record.default_timezone = :local
# デフォルトのロケールを日本語に設定
config.i18n.default_locale = :ja
# 使用可能なロケールに日本語を設定
config.i18n.available_locales = %i[ja]
end
end
モデルの日本語表記を作成
-
config/locale/ja.ymlを作成して以下のように編集
ja:
activerecord:
models:
# モデル名: モデルの日本語表記
memo: メモ
attributes:
# モデル名
memo:
# カラム名: カラムの日本語表記
content: メモ内容
このように書くことによって、Viewに書いてある<%= form.label :content %>だけでいい感じに置き換わってくれます。
日本語化出来ているか確認
- Railsを再起動する(停止ボタン->再生ボタン)
-
localhost:3000/memos/newでエラーを出して日本語化出来ているか確認する
メモにタイトルを設定できるようにする
マイグレーションファイル作成
メモを投稿できる機能を作る/マイグレーションファイル編集で編集したファイルを書き換えたくなりますが、一旦マイグレーションを行ったマイグレーションファイルを編集することはしてはいけません。そうすると、マイグレーションの意味が無くなってしまいます。
そのため、タイトルカラムを追加するマイグレーションを作成する必要があります。
今回はモデルの作成は不要なので、マイグレーションファイルのみを作成するコマンドを使用します。
memosテーブルにString型のTitleカラムを追加したいので、Generator argumentsはAddTitleToMemos title:stringとなります。
ここで、Text型ではなくString型を使う理由は、タイトルは255文字を超えないからです。
-
Ctrl+Alt+GもしくはTools->Run Rails Generator...をクリック -
rails g migrationを選択してEnter -
Genetaror argumentsにAddTitleToMemos title:stringを入力 -
OKをクリック
マイグレーションファイル確認
db/migrate/xxxxxxxx_add_title_to_memos.rbというマイグレーションファイルが作成されているので、見てみます。
class AddTitleToMemos < ActiveRecord::Migration[6.1]
def change
add_column :memos, :title, :string
end
end
今回は特に変更したい箇所は無いので変更しません。
ここでnull: falseによってnullを禁止しない理由は、後からnullを許可しないカラムを追加することは少しだけ難しいからです。
というのも、すでにレコードがある場合に必然的にtitleカラムがnullになってしまいます。
そのため、nullを許可しない場合はデフォルト値を設定するなどをする必要があります。
今回はi18nの問題もあり、表示側でnullであったら設定されていない旨の表示をすることにします。
マイグレーション実行
モデル編集
タイトルの文字数上限を50文字にします。
-
app/models/memo.rbにvalidates :title, length: {maximum: 50}を追記する
以下のようになっていればOKです。
class Memo < ApplicationRecord
# contentカラムのバリデーションを設定する
# presence: true - 空に出来ない
# lenght: {maximum: 1000} - 長さは最大1000文字
validates :content, presence: true, length: {maximum: 1000}
# titleカラムのバリデーションを設定する
# lenght: {maximum: 50} - 長さは最大50文字
validates :title, length: {maximum: 50}
end
コントローラ編集
カラムtitleの編集を許可する。
-
app/controllers/memos_controller.rbを開く - 21行目、
~permit(:content)を~permit(:content, :title)に変更する
以下のようになっていればOKです。
class MemosController < ApplicationController
def index
# すべてのメモを取得する
@memos = Memo.all
end
def show
# :idのメモを取得する
memo_id = params[:id]
@memo = Memo.find(memo_id)
end
def new
# 空のメモを作成する
@memo = Memo.new
end
def create
# 受け入れるパラメータを定義
# requireにはモデル名、permitにはカラム名
memo_param = params.require(:memo).permit(:content, :title)
# メモの中身を埋めて作成
@memo = Memo.new(memo_param)
# セーブする(データベースに書き込む)
if @memo.save
# 成功した場合はメモ一覧にリダイレクト
redirect_to(memos_path)
else
# エラーが発生した場合はnew(フォーム)を再表示する
render :new
end
end
end
View書き換え
以下のように編集します。
index
タイトルを表示するようにする。
<h1>メモ一覧</h1>
<ul>
<% @memos.each do |memo| %>
<%= link_to memo do %>
<li><%= memo.title.blank? ? 'タイトルなし' : memo.title %>: <%= memo.content %></li>
<% end %>
<% end %>
</ul>
<%= link_to('新規作成', new_memo_path) %>
<%= link_to('戻る', :back) %>
show
タイトルを表示するようにする。
<h1>メモ閲覧</h1>
<h2><%= @memo.title.blank? ? 'タイトルなし' : memo.title %></h2>
<pre><%= @memo.content %></pre>
<%= link_to('戻る', :back) %>
new
タイトルの入力フィールドを追加する。
<h1>メモ作成</h1>
<%# エラーがあったら表示する %>
<% if @memo.errors.any? %>
<ul>
<% @memo.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<%# modelにはコントローラで作った空のメモを指定する %>
<%= form_with(model: @memo, local: true) do |form| %>
<div class="field">
<%# タイトルを入力するテキストフィールド(labelはその説明) %>
<%= form.label :title %><br>
<%= form.text_field :title %>
</div>
<div class="field">
<%# メモ内容を入力するテキストエリア(labelはその説明) %>
<%= form.label :content %><br>
<%= form.text_area :content %>
</div>
<div class="actions">
<%# 送信ボタン %>
<%= form.submit %>
</div>
<% end %>
<%= link_to('戻る', :back) %>
モデルの日本語表記を作成
-
config/locale/ja.ymlを以下のように編集
title: タイトルを追加しています。
ja:
activerecord:
models:
# モデル名: モデルの日本語表記
memo: メモ
attributes:
# モデル名
memo:
# カラム名: カラムの日本語表記
content: メモ内容
title: タイトル
ブラウザで確認
- ブラウザで
localhost:3000/memosにアクセスする
メモのタイトルが表示されていて、タイトル付きのメモを新規作成できるようになっています。
完成!
お疲れさまでした!
もし間違っている所や指摘がありましたら伝えて頂けるとありがたいです。
あとよろしければLGTMもよろしくお願いします!
時間があれば、編集や削除機能の付け方やテストの書き方の記事なども作成するかもしれません。
























