【Rails】i18n で日本語化する方法
目次
はじめに
i18nというデフォルトでRailsに同梱されているgemを使ってRailsアプリを日本語化しました。
ここでいう日本語化というのは、ビューファイルには日本語を記述せずにブラウザ上の表示は日本語になっていることを指します。
具体例を手を動かしながら進めると理解の助けになるかと思います。
実装
実装手順は大まかに次の通りです。
Railsアプリを新しく作成します。
$ rails new i18n_practice
Railsのアプリケーション設定
config/application.rbにデフォルトで日本語の辞書を読み込むように設定します。また、読み込む辞書ファイルをconfig/locales/配下の全てのrb, ymlファイルに設定します。
次の2行を追加します。
config.i18n.default_locale = :ja config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
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 I18nPractice class Application < Rails::Application config.load_defaults 5.2 config.i18n.default_locale = :ja config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] end end
モデルとコントローラー、ビューを作成
モデルとコントローラーを作成します。
$ rails g model user name:string email:string password:string ... $ rails g controller users index new ...
テーブルを作成します。
$ rails db:migrate
ルーティング設定とビューを編集します。
ルーティングにルートへのアクセスを追加し、あとでform_withヘルパーを使うときに楽なのでリソースルーティングにします。
Rails.application.routes.draw do root 'users#index' resources :users, only: %i[index new] end
ビューを次のように編集します。
<h1>Users#index</h1> <p>インデックス</p> <p>サッカー</p> <p>銀行</p> <%= form_with model: @user, local: true do |form| %> <div> <%= form.label :name %> <%= form.text_field :name %> </div> <div> <%= form.label :email; %> <%= form.email_field :email %> </div> <div> <%= form.label :password %> <%= form.password_field :password %> </div> <div> <%= form.submit '送信' %> </div> <% end %> <div><%= link_to 'new', new_user_path %></div>
<h1>Users#new</h1> <p>新しい</p> <p>野球</p> <p>川岸</p> <%= form_with url: "#", local: true do |form| %> <div> <%= form.label :name %> <%= form.text_field :name %> </div> <div> <%= form.label :email; %> <%= form.email_field :email %> </div> <div> <%= form.label :password %> <%= form.password_field :password %> </div> <div> <%= form.submit '送信' %> </div> <% end %> <div><%= link_to 'index', users_path %></div>
現時点での表示は次の通りです。
コードを見てわかるように今は直接日本語をコードに書いています。これをi18nを使ってコードに日本語は書かず、辞書ファイルを用意することにより同じ表示を実装します。
辞書ファイルの作成( ja.yml )
辞書ファイルを作成します。辞書ファイルはconfig/locales配下に配置します。
デフォルトでconfig/localesにen.ymlがありますがこれは使わないので削除します。
config └── locales ├── activerecord │ └── ja.yml └── views └── ja.yml
lazy lookup記法で簡潔に辞書ファイルを記述することができます。
activerecord/ja.ymlにはモデルに関連することを記述しviews/ja.ymlにはビューに関連することを記述します。
モデルに関する辞書を読み込むことでform_withヘルパーなどでモデルのインスタンス変数を渡した際に自動で紐つけて日本語化してくれます。
ja: activerecord: models: user: ユーザー attributes: user: id: ID name: 名前 email: メールアドレス password: パスワード attributes: created_at: 作成日 updated_at: 更新日
コントローラーやアクションを越えて使うような単語はdefaultsなどにまとめて設定すると便利です。
ja: defaults: send: 送信 users: index: index: インデックス soccer: サッカー bank: 銀行 new: new: 新しい baseball: 野球 bank: 川岸
ビューを辞書から参照するように書き換える
i18nのtranslateメソッドを使うことにより辞書を読みんで多言語化することができます。
埋め込みRubyでは次のように実装します。
<%= translate '.title' %>
translateメソッドは省略することもできます。
<%= t '.title' %>
今回のビューファイルは次のように書き換えることができます。
form_withヘルパーにモデルのインスタンス変数を渡している場合はモデルに関する辞書を自動に読み込んでくれます。
<h1>Users#index</h1> <p><%= translate '.index' %></p> <p><%= t '.soccer' %></p> <p><%= t '.bank' %></p> <%= form_with model: @user, local: true do |form| %> <div> <%= form.label :name %> <%= form.text_field :name %> </div> <div> <%= form.label :email; %> <%= form.email_field :email %> </div> <div> <%= form.label :password %> <%= form.password_field :password %> </div> <div> <%= form.submit (t 'defaults.send') %> </div> <% end %> <div><%= link_to 'new', new_user_path %></div>
form_withヘルパーにURLを渡している場合、明示的にモデルを指定することにより読み込む辞書を判断してくれます。
<h1>Users#new</h1> <p><%= translate '.new' %></p> <p><%= t '.baseball' %></p> <p><%= t '.bank' %></p> <%= form_with url: "#", local: true do |form| %> <div> <%= form.label :name, User.human_attribute_name(:name) %> <%= form.text_field :name %> </div> <div> <%= form.label :email, User.human_attribute_name(:email) %> <%= form.email_field :email %> </div> <div> <%= form.label :password, User.human_attribute_name(:password) %> <%= form.password_field :password %> </div> <div> <%= form.submit (t 'defaults.send') %> </div> <% end %> <div><%= link_to 'index', users_path %></div>
これでコードに日本語表記はないですが、ブラウザの表示は日本語化されています。
参考文献
まとめ
辞書ファイルを作成しビューのコードに直接日本語を記述しない方法を実装しました。
用途に沿ってファイル分割をすることにより可読性もメンテナンス性も上がると思います。
なので、なるべく日本語化(多言語化)は辞書ファイルから読み込む方法で実装するべきだと感じました。
rails-i18nといったgemを使うと一般的な用語(エラーや単位など)は多数の言語に対応できるようなので時間があるときに触ってみたいと思います。
終わりに
最初は理解が難しかったですが手を動かしているうちに理解できるようになりました。
Railsの便利さには日々驚かされます。
参考文献
Railsのシンプルなログイン機能 Part3
目次
はじめに
ログイン機能の勉強として機能を細分化しつつ実装します。
理解するための実装なので設計上好ましくない実装が含まれます。できるだけシンプルに実装し、理解し易さを求めたので今回のような実装になりました。ないとは思いますが、後述するコードを参考にする際はお気をつけください。
- 環境
バージョン | |
---|---|
OS | OS X 10.15.6 |
ruby | 2.6.4 |
rails | 6.0.3 |
前回の続きをやっていきます。前回はパスワードの暗号化や登録情報のバリデーションを実装しました。それに次の項目を加えます。
- ユーザー編集
- ユーザー削除
設計
- データベース
カラム | 用途 | データ型 |
---|---|---|
id | 自動生成のID | intger |
name | ユーザーネーム | string |
password_digest | パスワード | string |
機能(追加)
ユーザー編集機能
ユーザー削除機能
ビュー
ファイル名 | 内容 |
---|---|
index.html.erb | ユーザー一覧 |
new.html.erb | 登録画面 |
edit.html.erb | 編集画面 |
実装
ユーザー編集機能の追加
編集をする時の流れは以下の通りです。
① ユーザー一覧の編集したいユーザーの編集ボタンを押す。
② ルーターによりeditアクションが実行され編集ページにリダイレクトされる。
(この時、編集したいユーザーの情報がインスタンス変数として渡される。)
③ ユーザー情報を編集し、更新ボタンを押す。
④ ルーターによりupdateアクションが実行され成功すればユーザー一覧にリダイレクトし、失敗したら編集ページにエラー表示をする
- ルーティングの設定
次のようにルーティングを設定します。
Rails.application.routes.draw do get 'users/index' get 'users/new' get 'users/home' get '/users/create', to: 'users#new' post '/users/create' get '/user/:id/edit', to: 'users#edit', as: 'edit_users' patch '/users/:id', to: 'users#update' root 'users#index' end
as: 'edit_users'も追加していることによりedit_users_pathヘルパーが使えるようになります。
- viewの編集
ユーザー一覧に編集ボタンを追加します。
<h1>ユーザー一覧</h1> <%= link_to '登録画面へ', '/users/new' %> <table> <tr> <th>ユーザー名</th> </tr> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= link_to 'Edit', edit_users_path(user) %></td> </tr> <% end %> </table>
rails server を起動してユーザー一覧ページの編集ボタンを開発ツールで見るとリンク先が<a href="/user/5/edit">Edit</a>
のようにレンダリングされているのがわかります。
- editアクションの追加
コントローラーを次のように変更します。
class UsersController < ApplicationController def index @users = User.all end def new @user = User.new end def home end def edit @user = User.find(params[:id]) end def create @user = User.new(user_params) if @user.save redirect_to '/users/index' else render '/users/new' end end private def user_params params.require(:user).permit(:name, :password, :password_cofirmation) end end
edit用のviewファイルも追加します。登録ページ(new.html.erb)を少し変えたものになります。
<h1>ユーザー編集</h1> <%= link_to 'ユーザー一覧', '/users/index' %> <form action="/users/<%= params[:id] %>" method="post"> <input type="hidden" name="_method" value="patch"> <%= hidden_field_tag :authenticity_token, form_authenticity_token %> <ul> <li> <label for="user_name">Name:</label> <input type="text" id="user_name" name="user[name]" value="<%= @user.name %>"> </li> <li> <label for="user_password">Password:</label> <input type="password" id="user_password" name="user[password]"> </li> <li> <label for="user_password">Password(confirm):</label> <input type="password" id="user_password_confirmation" name="user[password_confirmation]"> </li> <li> <input type="submit" value="編集"> </li> </ul> </form>
追加した1行は<input type="hidden" name="_method" value="patch">
です。
また、名前入力欄には編集前の名前を表示するためにinputタグのvalue属性をvalue="<%= @user.name %>"
にしています。フォームの送信先は<form action="/users/<%= params[:id] %>" method="post">
としています。次の項でupdateアクションを追加します。
- updateアクションの追加
Userコントローラーにupdateアクションを追加します。updateアクションはDBにユーザー情報を上書きするだけなのでviewファイルを新たに作る必要はありません。
class UsersController < ApplicationController def index @users = User.all end def new @user = User.new end def home end def edit @user = User.find(params[:id]) end def create @user = User.new(user_params) if @user.save redirect_to '/users/index' else render '/users/new' end end def create @user = User.find(params[:id]) if @user.update redirect_to '/users/index' else render '/users/edit' end end private def user_params params.require(:user).permit(:name, :password, :password_cofirmation) end end
createアクションと似ています。新しくUserオブジェクトを作るのではなくidでDBから検索し、paramsの値を引数にupdateメソッドでDBに保存します。この時Rails serverのログを見るとSQLのクエリが登録時と編集時で異なることがわかります。
登録時(INSERTでDBに保存している)
INSERT INTO "users" ("name", "password_digest", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "test"], ["password_digest", "$2a...KG"], ["created_at", "2020-09-29 06:16:15.541364"], ["updated_at", "2020-09-29 06:16:15.541364"]]
編集時(UPDATEでDBに保存している)
UPDATE "users" SET "name" = ?, "password_digest" = ?, "updated_at" = ? WHERE "users"."id" = ? [["name", "change3"], ["password_digest", "$2...li"], ["updated_at", "2020-09-29 06:16:29.407794"], ["id", 3]]
以上で編集機能が追加できました。
ユーザー削除機能の追加
削除をする時の流れは以下の通りです。
① ユーザー一覧の削除したいユーザーの削除ボタンを押す。
② ルーターによりdestroyアクションが実行され、確認メッセージをブラウザに表示した後ユーザーが削除される。
③ 削除完了後、ユーザー一覧にリダイレクトされる。
- ルーティングの設定
次のようにルーティングを設定します。
Rails.application.routes.draw do get 'users/index' get 'users/new' get 'users/home' get '/users/create', to: 'users#new' post '/users/create' get '/user/:id/edit', to: 'users#edit', as: 'edit_users' patch '/users/:id', to: 'users#update' delete '/users/:id', to: 'users#destroy', as 'destroy_users' root 'users#index' end
- viewの編集
ユーザー一覧に削除ボタンを追加します。
<h1>ユーザー一覧</h1> <%= link_to '登録画面へ', '/users/new' %> <table> <tr> <th>ユーザー名</th> </tr> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= link_to 'Edit', edit_users_path(user) %></td> <td><%= link_to 'Destroy', destroy_users_path(user), method: :delete, data: { confirm: 'Are you sure' } %></td> </tr> <% end %> </table>
- destroyアクションの追加
Userコントローラーにdestroyアクションを追加します。
class UsersController < ApplicationController def index @users = User.all end def new @user = User.new end def home end def edit @user = User.find(params[:id]) end def create @user = User.new(user_params) if @user.save redirect_to '/users/index' else render '/users/new' end end def create @user = User.find(params[:id]) if @user.update redirect_to '/users/index' else render '/users/edit' end end def destroy @user = User.find(params[:id]) @user.destroy redirect_to users_index_path end private def user_params params.require(:user).permit(:name, :password, :password_cofirmation) end end
これでユーザーが削除できるようになりました。削除時のSQLは次のようになっていることがRails severのログから確認できます。
User Destroy (0.9ms) DELETE FROM "users" WHERE "users"."id" = ? [["id", 3]]
まとめ
今回でユーザーの編集・削除機能が完成しました。
ログイン機能を満たす為には認証機能を用いて編集や削除できる範囲を自分のユーザーのみにする必要があります。
続きとして認証機能を追加していきたいと思います。
参考文献
Railsのシンプルなログイン機能 Part2
目次
はじめに
ログイン機能の勉強として機能を細分化しつつ実装します。
理解するための実装なので設計上好ましくない実装が含まれます。できるだけシンプルに実装し、理解し易さを求めたので今回のような実装になりました。ないとは思いますが、後述するコードを参考にする際はお気をつけください。
- 環境
バージョン | |
---|---|
OS | OS X 10.15.6 |
ruby | 2.6.4 |
rails | 6.0.3 |
前回の続きをやっていきます。前回はユーザー情報をデータベースに登録する機能を実装しました。それに次の項目を加えます。
- パスワードを保存する際の暗号化
- 登録情報のバリデーション
- エラー処理
設計
- データベース
あとで実装するパスワードの暗号化のためにパスワードのカラム名をpassword_digestというカラムに変更します。
カラム | 用途 | データ型 |
---|---|---|
id | 自動生成のID | intger |
name | ユーザーネーム | string |
password_digest | パスワード | string |
機能(追加)
パスワードを暗号化してデータベースに保存する
登録情報(ユーザーネーム、パスワード)の登録制限機能(バリデーション)
項目2で設定した入力制限により登録ができない時の処理(エラー処理)
ビュー
ファイル名 | 内容 |
---|---|
index.html.erb | ユーザー一覧 |
new.html.erb | 登録画面 |
実装
パスワードを暗号化してデータベースに保存する
パスワードの暗号化機能に必要なことは大きく分けると以下の通りです。
・has_secure_passwordメソッドを使う
・パスワードはDBのpassword_digestカラムに保存する
・ bcrypt gemの追加
- データベースの変更
パスワードを保存するカラム名をpassword_digestに変更します。
次のコマンドでマイグレーションファイルを作成します。
$ rails g migration rename_password_password_digest_column_to_Users
作成したマイグレーションファイルを次のように変更します。
class RenamePasswordPasswordDigestColumnToUsers < ActiveRecord::Migration[6.0] def change rename_column :users, :password, :password_digest end end
最後にdb:migtateを実行しDBに反映させます。
$ rails db:migrate
Userモデルを確認すると、annotateによるスキーマ情報が変更されているのがわかります(実際にDBも変更されています)。
# == Schema Information # # Table name: users # # id :integer not null, primary key # name :string # password_digest :string # created_at :datetime not null # updated_at :datetime not null # class User < ApplicationRecord end
- Userコントローラーの編集
has_secure_passwordではpassword属性とpassword_confirmation属性のものがフォームから送られてきた時、その2つが同じ値ならばパスワードを暗号化してDBのpassword_digestカラムに暗号化されたパスワードを保存します。そのため、strong parametersに:password_cofirmationを追加します。
class UsersController < ApplicationController def index @users = User.all end def new end def home end def create @user = User.new(user_params) @user.save redirect_to '/users/index' end private def user_params params.require(:user).permit(:name, :password, :password_cofirmation) end end
- viewファイルの編集
Userコントローラーと同様にpassword_cofirmation属性のinputタグを追加します。
<h1>ユーザー登録</h1> <%= link_to 'ユーザー一覧', '/users/index' %> <form action="/users/create" method="post"> <%= hidden_field_tag :authenticity_token, form_authenticity_token %> <ul> <li> <label for="user_name">Name:</label> <input type="text" id="user_name" name="user[name]"> </li> <li> <label for="user_password">Password:</label> <input type="password" id="user_password" name="user[password]"> </li> <li> <label for="user_password">Password(confirm):</label> <input type="password" id="user_password_confirmation" name="user[password_confirmation]"> </li> <li> <input type="submit" value="登録"> </li> </ul> </form>
- bcryptの追加
Gemfileにbcryptを追加してbundle installを実行します。
bcryptはデフォルトでコメントアウトされている場合があるのでコメントアウト されていたらコメントアウトを解除し、なければ追加します。
... gem 'bcrypt', '3.1.7' ...
$ bundle install
- has_secure_passwordの追加
userモデルにhas_secure_passwordを追加します。
# == Schema Information ... class User < ApplicationRecord has_secure_password end
以上で、パスワードの暗号化が実装されました。暗号化する前と後のデータベースの中身は次の通りです。
SQLite version 3.28.0 2019-04-15 14:49:49 Enter ".help" for usage hints. sqlite> SELECT "users".* FROM "users"; ... 8|foo|bar|2020-09-28 06:06:23.205372|2020-09-28 06:06:23.205372 9|hoge|$2a$12$deW7iUy7UnXXUMAYPLur.OHd7G7lhzTbI0AwA95I7XO.QOBZjNe4e|2020-09-28 06:17:23.433464|2020-09-28 06:17:23.433464 sqlite>
一番左のカラムがidであり、idが9のデータを挿入する前に暗号化を追加しました。左から3番目のカラムがpassword_digestのカラムで暗号化されているのがわかります。
登録情報(ユーザーネーム、パスワード)の登録制限機能(バリデーション)
ここでは、名前やパスワードの登録に制限をかけます。具体的には次の通りです。
・名前:50文字以内。空欄禁止。
・パスワード:8文字以上。空欄禁止。
パスワードに関して、8文字以上の制限だけで空欄禁止も含むかと思われますが、文字数制限だけでは6文字分の空白スペースなどに対応できないため空白禁止の制限も追加します。
この制限を実装するにはUserモデルにバリデーション機能を追加します。
- Usesrモデルの編集
Userモデルに次のようにバリデーションを追加します。
# == Schema Information ... class User < ApplicationRecord has_secure_password validates :name, presence: true, length: { maximum: 50 } validates :password, presence: true, length: { minimum: 8 } end
これにより、名前は1文字以上50文字以内(空欄禁止)でパスワードは8文字以上という制限が追加されました。
登録制限は実装できましたが、このままでは登録できなかった時と登録できた時の違いがわかりません。そこで、次の項で登録失敗の時はエラーを表示するようにします。
登録ができない時の処理(エラー処理)
エラー処理の手順は次の通りです。
①Userコントローラーに登録成功時と失敗時の分岐を追加する。
②Userコントローラーのnewメソッドにインスタンス変数を追加する。
③viewファイルにエラーメッセージの表示を追加
- Userコントローラーの変更
次のようにUserコントローラーを修正します。
class UsersController < ApplicationController def index @users = User.all end def new @user = User.new end def home end def create @user = User.new(user_params) if @user.save redirect_to '/users/index' else render '/users/new' end end private def user_params params.require(:user).permit(:name, :password, :password_cofirmation) end end
newメソッドでは空のインスタンス変数を作成しています。これがないと登録ページにアクセスした時、インスタンス変数@Userがnilになりエラーが出ます。
登録成功時と失敗時の分岐はcreateメソッドのif分で実装しています。@user.saveはDBへの保存は成功した時trueを返し、失敗した時(登録制限に引っ掛かった時)falseを返します。成功時は今まで通りユーザー一覧にリダイレクトし、失敗時は登録ページ(現在の)にリダイレクトしエラーを表示します。
- viewファイルの変更
viewファイルを次のように修正します。
<h1>ユーザー登録</h1> <%= link_to 'ユーザー一覧', '/users/index' %> <form action="/users/create" method="post"> <%= hidden_field_tag :authenticity_token, form_authenticity_token %> <% if @user.errors.any? %> <div id="error_explanation"> <div> The form contains <%= pluralize(@user.errors.count, "error") %>. </div> <ul> <% @user.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <ul> <li> <label for="user_name">Name:</label> <input type="text" id="user_name" name="user[name]"> </li> <li> <label for="user_password">Password:</label> <input type="password" id="user_password" name="user[password]"> </li> <li> <label for="user_password">Password(confirm):</label> <input type="password" id="user_password_confirmation" name="user[password_confirmation]"> </li> <li> <input type="submit" value="登録"> </li> </ul> </form>
登録に失敗した時は@userにエラーのオブジェクトが追加されます。<% if @user.errors.any? %>とすることで、エラーがある時はエラーを表示し、エラーがないときは通常の登録フォームを表示することができます。
全て空欄でフォームを送信すると次のようになります。
passwordとpassword_confirmationが違う時は次のようなエラーになります。
エラー表示は実装できましたが、今のままだとエラー表示後にブラウザを再読み込みするとRailsのエラーになってしまいます。そこでルーティングを次のように変更します。
Rails.application.routes.draw do get 'users/index' get 'users/new' get '/users/create', to: 'users#new' post 'users/create' root 'users#index' end
フォームの送信はPOSTリクエストで送信されるようにHTMLを作成したがブラウザの読み込みはGETリクエストなのでcreateアクションにGETリクエストが来た時のルーティングをnewアクションに設定しています。
まとめ
今回でユーザーの登録機能が完成しました。
次回はユーザーの編集・削除機能の追加となります。
参考文献
Railsのシンプルなログイン機能 Part1
目次
はじめに
ログイン機能の勉強として機能を細分化しつつ実装します。今回はユーザーをデータベースに登録し、ユーザーの一覧を表示されるところまで。
理解するための実装なので設計上好ましくない実装が含まれます。できるだけシンプルに実装し、理解し易さを求めたので今回のような実装になりました。ないとは思いますが、後述するコードを参考にする際はお気をつけください。
- 環境
バージョン | |
---|---|
OS | OS X 10.15.6 |
ruby | 2.6.4 |
rails | 6.0.3 |
設計
- データベース
カラム | 用途 | データ型 |
---|---|---|
id | 自動生成のID | integer |
name | ユーザーネーム | string |
password | パスワード | string |
機能
ユーザー登録
ユーザー一覧表示
ここでは、ユーザーを登録して、ユーザー一覧を表示するだけです。
ユーザー削除やユーザー編集、認証機能はここでは実装しません。ビュー
ファイル名 | 内容 |
---|---|
index.html.erb | ユーザー一覧 |
new.html.erb | 登録画面 |
実装
- 新しいRailsアプリを作成。
$ rails new simple_login
gem annotate を追加。(annotateの追加方法)
- modelとデータベース作成
下記コマンドでユーザーモデルを作成。
$ rails g model User name:string password:string
下記コマンドでデータベースを作成。
$ rails db:migrate
- controller作成
$ rails g controller Users index new create
- ルーティング設定
コントローラーを作成した際に生成されたroutes.rbを次のように書き換える。
Rails.application.routes.draw do get 'users/index' get 'users/new' post 'users/create' root 'users#index' end
Usersコントローラーのcreateメソッドはユーザー登録のメソッドなのでgetからpostに変更する。また、ルートへのパスをユーザー一覧画面であるindexに変更する。
- viewの編集
① 登録画面( new.html.erb )
基本的にはよくあるHTMLのフォームです。4行目はPOSTリクエストを送るためのRailsのおまじないだと思ってください(CSRF保護を通過するためらしいです)。
<h1>ユーザー登録</h1> <%= link_to 'ユーザー一覧', '/users/index' %> <form action="/users/create" method="post"> <%= hidden_field_tag :authenticity_token, form_authenticity_token %> <ul> <li> <label for="user_name">Name:</label> <input type="text" id="user_name" name="user[name]"> </li> <li> <label for="user_password">Password:</label> <input type="password" id="user_password" name="user[password]"> </li> <li> <input type="submit" value="登録"> </li> </ul> </form>
② ユーザー一覧 ( index.html.erb )
<h1>ユーザー一覧</h1> <%= link_to '登録画面へ', '/users/new' %> <table> <tr> <th>ユーザー名</th> </tr> <% @users.each do |user| %> <tr> <td><%= user.name %></td> </tr> <% end %> </table>
- controllerの編集
① indexメソッド
登録されているユーザーをUser.allで全て取得してindexビューに渡します。
② newメソッド
newビューを表示するだけなので何も記述しません。
③ createメソッド
フォームのページからのparamsをプライベートクラスに渡しuserに関するものだけにします。それを元にUser.new(user_params)でフォームから送られてきたnameとpasswordで新しいオブジェクトを作成します。そのオブジェクトをインスタンス変数@userに代入します。インスタンス変数@userをsaveメソッドでデータベースに保存します。最後にユーザー一覧にリダイレクトします。
class UsersController < ApplicationController def index @users = User.all end def new end def create @user = User.new(user_params) @user.save redirect_to '/users/index' end private def user_params params.require(:user).permit(:name, :password) end end
- 今回の設計要件は以上で満たしました。
まとめ
以上で、ユーザー登録とユーザー一覧表示の機能は実装できました。ただ、これだけ質素な機能でも考慮すべき点がいくつもあります。
- 登録情報のバリデーション
- パスワードを保存する際の暗号化
- ユーザー一覧のページネーション
- エラー処理
今の登録情報は名前とパスワードですが認証機能がないので、ただuserテーブルの”name”と”password”というカラムにデータを保存しているだけの状態です。ログイン機能を実装するには次の項目も実装する必要があります。
- ユーザー削除
- ユーザー編集
- 認証機能
- リファクタリング(フォームヘルパーやパーシャルの活用)
- RESTfullなルーディング
上記の項目を追加してやっと”ただのログイン機能”が実装できます。これに加えてユーザーの投稿やいいね機能などSNSの基本的な機能を追加してやっとアプリケーションらしくなっていきます。いきなりは難しいので徐々に機能追加していきたいと思います。
参考文献
データベースのスキーマ情報をmodelファイルに追加するgem、annotateの使い方
annotateの使い方
各モデルのスキーマ情報をファイルの先頭もしくは末尾にコメントとして書き出してくれるgem。
例えば、app/model/user.rb ファイルの最初にテーブルのカラム等を記述してくれる。
① Gemfileに追加
gem 'annotate'
② gemとdbを更新。
$ bundle install $ rails g annotate:install $ rails db:migrate
③ スキーマ情報が書き出される。
# == Schema Information # # Table name: users # # id :integer not null, primary key # crypted_password :string # email :string not null # salt :string # created_at :datetime not null # updated_at :datetime not null # # Indexes # # index_users_on_email (email) UNIQUE # class User < ApplicationRecord end
参考文献
テスト投稿
目次
はじめに
プログラミングの勉強したことをまとめていきます。
マークダウンテスト
はてなブログのマークダウン記法の確認です。
Hello Worldをいくつかの言語で書いてみます。
1. C言語
#include <stdio.h> int main(void) { printf("Hello World\n"); return (0); }
2. C++
#include <iostream> using namespace std; int main() { cout << "Hello World" << endl; return(0); }
3. Ruby
puts "Hello World"
4. Python
print("Hello World")
5. PHP
<?php echo "Hello World\n" ?>
感想
目次を作るのが楽なような制約があるような。
タブ入力はできないのかな?
最近はマークダウン記法を試しているけどプラットフォームによる違いが若干あるのがややこしい。
これからはRailsの勉強したことをまとめていきたい。