Rails基礎 ストロングパラメータとバリデーション
今回はユーザーの入力値チェックを行う機能について書いていく。
ストロングパラメータとは?
WEB上でユーザーが送信してきたパラメータの内容をチェックしてから受け取る仕組みのこと。
悪意のあるデータを事前に防ぐことができる。
事前に受け付ける項目を指定しておくことで、裏で持っているユーザーからの入力を受け付けていない項目に値が入っていたら弾いてくれる。
フォームから送られてくるパラメータが対象で、create
やupdate
などの機能に実装する。
書き方例
post
モデルのcreate
に機能を実装したい場合
controller
に記述していく。
def create @post = Post.new(params.require(:post).permit(:title,:body)) end
まず、require
メソッドで対象とするモデル、キーを指定することで、それに紐付いている値だけを抽出することが可能になる。
そしてpermit
メソッドで許可する値を明示的に指定してあげることで、他の項目が悪意ある改ざんを受けたとしてもスルーしてくれるようになる。
(この場合、titleとbody以外にカラムがあったとしてもそのカラムの登録・変更は受け付けない)
メソッドに切り出す
上記ではcreate
メソッドに直接書きましたが、繰り返されることが多い処理なので(登録と編集とか)
privateメソッドに切り出すのが慣習のよう。
def create @post = Post.new(post_params) @post.save end private def post_params params.require(:post).permit(:title,:body) end
メソッド名はモデル名_params
としてあげるのが一般的らしい。
バリデーションとは?
先程のストロングパラメータとは違い、バリデーションは入力された値そのものに対してチェックを行っていく。
例えば、入力必須の項目であったり、最低文字数が決まっている、メールアドレスだと@が入っているかどうか、等。
バリデーションはapp/models/post.rb
に記入していく。
class Post < ApplicationRecord validates :title, presence: true, length: {minimum: 3, message: 'Too short to post!'} validates :body, presence: true end
タイトルの行は「タイトルに対してのバリデーションで、必須項目だよ、最低文字数は3文字で、条件が満たない場合は「Too short to post!」とエラーメッセージを返してね」という意味になる。
バリデーションが成功したかどうかは.save
の返り値でbool型で返却されるので、controller
で結果を受け取って処理を行う。
def create @post = Post.new(post_params) if @post.save redirect_to posts_path else render 'new' end end
これで、成功すればposts_pathにリダイレクトし、そうじゃない場合はnewと同じviewを表示してくれる。
あとはviewでエラーメッセージを表示するようにすれば良い。
<% if @post.errors,messages[:title].any? %>
でエラーメッセージがあるかどうかを調べ、エラーが有る場合(=true)は、
<%= @post.errors.messages[:title][0] %>
としてあげれば、複数のエラーがあった場合も、最初のエラーが消えるまで最初の1つ表示してくれる。 (必須チェック→文字数チェック、のように、順番も意識したほうが良さそう)
Rails基礎 フォームヘルパー(form_for)
フォームヘルパーとは?
Railsでフォームを作成するためのヘルパー。 これを使用すると簡単な記述でフォームを作成することが可能になる。 内部ではHTMLを生成してくれる。input、textarea、submit等
form_for
form_tag
form_with
と3種類用意されているが、Rails5.1で登場したform_withは他2つを統合したものになるため、 Rails5.1以降はform_withを使用することが推奨されている
今回ドットインストールに出てきたのがform_for
だったため、これについて書いていく。
form_for
form_forは特定のモデルを編集・作成するのに向いている。 フォームとモデルオブジェクトを紐付けることで簡単に作成することができる。
html.erbファイルに記述していく。
<%= form_for @post, url: posts_path do |f| %> <p> <%= f.text_field :title, placeholder: 'enter title' %> </p> <p> <%= f.text_area :body, placeholder: 'enter body text' %> </p> <p> <%= f.submit %> </p> <% end %>
ちなみに、1行目を省略しないで書くと以下
<%= form_for(@post, {url: posts_path}) do |f| %>
オプション
オプション | 説明 | デフォルト値 |
---|---|---|
:as | ハッシュのキー名前 | |
:url | フォームの送信先 | |
:namespace | 名前空間の設定 | |
:method | メソッド(get, post, patch, put, deleteなど) | |
:authenticity_token | 認証トークン | |
:remote | JavaScriptを使うか | false |
:enforce_utf8 | utf8用の非表示用を出力するか? | true |
:html | タグの属性 | |
:format | フォーマット |
form_forでの入力は、上記の場合post[属性名]
というフォーム名を持つ。
今回だと:title
と:body
キーを持つハッシュがparams[:post]
に入る。
:url
オプションを渡しルーティングパスを指定している。
Controllerで作成したインスタンスが空であればcreateアクション、そうでなければupdateアクションへ自動的に振り分けてくれる。
fオブジェクト
を使用することでテキストボックスをはじめ、チェックボックスやパスワード入力ボックス、ファイル選択フォーム等を簡単に作成することが可能になる。
- check_box…チェックボックス
- radio_button…ラジオボタン
- text_area…テキストエリア
- password_field…パスワード入力ボックス
- hidden_field…隠しフィールド
- label…ラベルタグ
- text_field…テキストボックス
- file_field…ファイル選択ボックス
- select…選択ボックス
- email_field…メールアドレス入力ボックス
- number_field…数値入力ボックス
- range_field…範囲選択バー
- search_field…検索ボックス
- telephone_field…電話番号入力ボックス
- url_field…URL入力ボックス
- submit…サブミットボタン
- datetime_select…日時選択ボックス
- color_field…色の入力欄
- date_field…日付の入力欄
- datetime_field…日時の入力欄
- datetime_local_field…ローカル日時の入力欄
- month_field…月の入力欄
- time_field…時間の入力欄
- week_field…週の入力欄
- date_select…日付選択ボックス
- time_select…時間選択ボックス
等…最後に_tag
をつけると汎用的な○○
ができるらしい。
いずれ各メソッドがどんな形でこれらを生成するのか確かめたい。
参考
Rails基礎 link_toヘルパー
link_toとは
viewでリンクを表示させることが出来る。最終的には<a>
タグを生成して表示される。
helperメソッドの1つ。
link_toメソッドに表示させたい文字列とリンク先を引数として渡す必要がある。
link_to '表示させる文字列',リンク先のパス(URL)
URLを指定
<%= link_to 'Title','http://www…./' %>
ルーティングの名前で指定
ルーティングの名前の後ろに_path
をつけてあげると同じアプリケーション内へのリンクを作成してくれる。
基本的な使い方。
$rails routes
を実行したときに表示されるroute一覧を見て、Prefix
の列に表示されている名前を指定してあげればOK。
# users#new <%= link_to '新規登録', new_user_path %>
また、idを指定してあげることで特定のユーザーの詳細ページにリンクしたい場合などは、パスに引数として変数(この場合はuser
)を渡してあげることで、
この変数に入っているユーザーデータのidを元にリンク先をいい感じに解釈して設定してくれる。
# users#show <%= link_to User.Name, user_path(user) %>
リンク関連のビューヘルパーについて
link_to の他にもurl_for、link_to_if / link_to_unless、link_to_inless_current
を紹介してくれています。
その他ヘルパー
画像にリンクを貼る
上記では、対象の文字列をクリックすることでリンク先に飛べるようになりますが、
画像にリンクをつけたい場合は、image_tag
ヘルパーというものを使用すれば良い。
また画像はassets/images
ディレクトリがデフォルトで用意されているのでそこに入れればOK。
画像の表示のみ
<%= image_tag 'image.png' %>
また、画像にクラスを指定したい場合は
<%= image_tag 'image.png' class: 'logo'%>
のように記述すれば適用させてくれる。
画像にリンク
<%= link_to image_tag('image.png' class: 'logo'), root_path %>
このようにlink_to
とimage_tag
を組み合わせると画像に対しリンクが貼られるようになる。
Rails基礎⑥ ビューの作成
ビューの作成
例えば、postsコントローラーのindexアクションに対応するviewはapp/view/posts/index.html.erb
というファイルを作成する。
ERBとは?
Railsが用意しているテンプレートエンジンのこと。
これを使用することで、
<% %>
でRubyのソースコードとして実行することができたり、<%= %>
とすることで、実行結果(コントローラーで定義したインスタンス変数等)が使用できるようになります。
記述ルール
viewの記述
controllerに
def index @posts = Post.all.order(created_at: 'desc') end
とあった場合、@posts
に取得したデータが入っている。
Post.all
は内部で
SELECT "posts".* FROM "posts"
というSQLが発行されているし、
上記のPost.all.order(created_at: 'desc')
では、
SELECT "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC
というSQLをActiveRecordが代わりに発行してくれている。
そして、app/view/posts/index.html.erb
に
<h2>My Posts</h2> <ul> <% @posts.each do |post| %> <li> <%= post.title %> </li> <% end %> </ul>
とすると、以下のようなページが出来上がる。
rootパスの設定
先程のページはURLの最後に/posts
をつけなければいけないが、
そのページがメインになる場合はrootパスに設定してあげることで、その必要がなくなる。
routes.rb
にrootを設定する。
Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html resources :posts root 'posts#index' #追加 end
基本レイアウトの設定
特に指定がない場合、アプリケーション全体でapp/views/layouts/application.html.erb
というファイルが読み込まれる。
<!DOCTYPE html> <html> <head> <title>Myblog</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <%= yield %> </body> </html>
viewで書いたコードは上記の<%= yield %>
の部分で読み込まれる。
また、CSSはapp/assets/stylesheets/application.css
が読み込まれる。
app/views/layouts/application.html.erb
<!DOCTYPE html> <html> <head> <title>Myblog</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <div class="container"> <%= yield %> </div> </body> </html>
application.css
.container { width:400px; margin: 20px auto; } body{ font-family: Verdana, sans-serif; font-size: 14px; } h2{ font-size: 16px; padding-bottom: 10px; margin-bottom: 15px; border-bottom: 1px solid #ddd; } ul > li { margin-bottom: 5px; }
とすると、以下のように表示されるようになる
Rails基礎⑤ コントローラーの作成
コントローラーの作成
$ rails g controller [コントローラー名]
Controllerでは複数のデータを扱うため、コントローラー名は複数形、頭文字は大文字にすること。
主に、controllerディレクトリにxxx_controller、viewディレクトリに新しいディレクトリ、テスト用のファイルなどが生成される。
ルーティングの設定
どのURLにアクセスされたときに、controllerのどのメソッドを実行するかを設定していく作業のこと。
config/routes.rb
に記述していく。
一般的な処理を一気に設定したい場合
resources :名称[複]
なので、
Rails.application.routes.draw do resources :コントローラー名 end
でOK。
これで、 index,show,new,create,edit,update,delete の7種類のアクションが一気に定義することができる。
特定のルーティングのみを指定したい場合、
Rails.application.routes.draw do resources :コントローラー名, only: [:index, :show] end
のようにonlyを使用する。
resource
resources とはまた別物となる。 indexアクションが定義されない、URI Pattersにidが含まれなくなる、といった違いがある。
Rails.application.routes.draw do resource :名称[単] end
ルーティングの確認
$ rails routes
で一覧を確認できる。
Prefix | Verb | URI Pattern | Controller#Action |
---|---|---|---|
posts | GET | /posts(.:format) | posts#index |
だとすると、「/postsでgetでアクセスしてきたら、postsコントローラーのindexアクションを実行」という意味。
参考
controllerにアクションを記述する
app/controller/名称_controller
に記述していく。
メソッドの形で記述していく。 アクション名=メソッド名なので、アクションを作成する場合はアクション名のメソッドを定義する必要がある。
アクションを表すメソッドはpublicで作成する必要がある。(Rubyはデフォルトがpublicとなっている)
Postsを作成日時の新しい順に並べてすべて取得したい場合は以下のように記述する。
def index @posts = Post.all.order(created_at: 'desc') end
Rails基礎④ 初期データの管理
DBの操作・確認
DBへの接続
$ rails dbconsole
もしくは、
$ rails db
デフォルトはSQLiteとなっている。
テーブルの確認
sqlite > .tables
モデル名Post
のデータを確認する
sqlite > Select * From Posts;
※テーブル名は複数形であることに注意。
DB操作から抜ける
sqlite > .quit
ファイルで初期データの管理をする
db/seeds.rb
Post.create(title: "hogehoge",body: "fugafuga")
これは、
post = Post.new(title: "hogehoge") post.body = "fugafuga" post.save
と同じで、ひとまとめにして登録ができる。
保存したい属性(カラム)をすべて引数で渡す必要がある。
登録できたかどうかをtrue
またはfalse
で返却してくれる。
newを使用することで、生成したインスタンスを受け取ることができるので、 インスタンスが必要な場合はnew~saveを使用することも検討する。
他の記述方法、初期データの登録方法は以下のサイトが勉強になった。
テーブルの中身をクリア
$ rails db:migrate:reset
seeds.rbで作成したデータをDBに流し込む
$ rails db:seed
マイグレーションファイルについて
マイグレーションファイルはデータベースを生成する際の設計図のようなもの。 これを実行することにより、その内容に基づいてテーブルを生成してくれる。
$ rails g model
を実行したときに一緒に生成されるが、
マイグレーションファイルのみ生成したい場合は
$ rails g migration マイグレーション名
を実行する。
db:migrate
を実行すると、形がほぼ完成してしまうので、あとで変更が難しくなってしまうため注意が必要(オプションやインデックスの追加等)。
Rails基礎③ モデルの作成
モデルの作成
$ rails generate model 名前 [カラム名:型] [オプション]
generateはgで省略することが出来るので、以下のようにも書ける
$ rails g model 名前 [カラム名:型] [オプション]
データ型
データ型 | 説明 |
---|---|
string | 文字列 |
text | 長い文字列 |
integer | 整数 |
float | 浮動小数 |
decimal | 精度の高い小数 |
datetime | 日時 |
timestamp | より細かい日時 |
time | 時間 |
date | 日付 |
binary | バイナリデータ |
boolean | Boolean型 |
オプション
オプション | 説明 | デフォルト値 |
---|---|---|
skip-namespace | 名前空間をスキップする | |
old-style-hash | 古いハッシュの形式を使う | |
-o, -orm=名前 | 使用するO/Rマッパー | active_record |
migration | マイグレーションファイルを生成するか | true |
timestamps | true | |
parent=名前 | ||
indexes | true | |
-t, test-frameword=名前 | 使用するテストフレームワーク | test_unit |
fixtures | フィクスチャを生成するか | true |
-r, fixture-replacement=名前 | フィクスチャを変更 | |
-f, force | ファイルが存在する場合に上書き | |
-q, quiet | 進捗状況を非表示 | |
-p, pretend | ドライラン | |
-s, skip | 既に存在するファイルについてはスキップ | |
-h, help | ヘルプを表示 |
例えば、タイトルと記事を持つブログアプリの場合
$ rails g model Post title:string body:text
また、モデルは個々のデータ構造を定義するため、名前を単数形にする。
その後、データ構造を反映させるために
$ rails db:migrate
を実行する。
データの格納
コンソールの起動
$ rails console
もしくは、省略記法を利用して
$ rails c
コンソールからデータを登録する
タイトル:title1
、内容をbody1
として登録したい場合、
コンソール上で
> p = Post.new(title: 'title 1', body: 'body 1') > p.save
と記述する。
Postは先程のモデルにつけた名前を指定。UserならUser.newとなる。
Post.new と p.save をわけずに、一度に書くことができる
> Post.create(title: 'title 2', body: 'body 2')
このように、SQLを発行しなくてもデータを格納できる仕組みを Active Record という。
Active Recordとは
Railsが採用しているO/Rマッパーのこと。 Railsでは、テーブルごとに作成されたモデルクラスを通じてデータベースに接続する。
O/Rマッパーとは?
O/R(Object/Relational)マッピングの考えに基づいて実装されたライブラリ。 オブジェクト指向プログラミング言語からRDBにアクセスする際の架け橋となる仕組みのこと。 プログラミング言語で扱うクラス・オブジェクトとRDBで扱うテーブル同士のリレーションが異なる仕組みのため、 その違いを吸収するために考えられた。
Active Recordの主な機能
コンソールを抜ける
> quit
とすれば、コンソールから抜けることができる。
モデルクラスとテーブルの命名ルール
モデルクラス名は単数形、テーブル名は複数形で表現すること。
2つ以上の単語を組み合わせたモデルクラスの場合、 テーブル名はアンダースコアで繋げた最後の単語を複数形とする決まり。
モデルクラス名 | テーブル名 |
---|---|
User | users |
UserItem | user_items |
テーブルのカラム名の命名ルール
ActiveRecordでは、レコードを識別するためのカラムはデフォルトでid
となる。
ActiveRecordでテーブルを作成すると、自動的に追加される。
また、created_at
、updated_at
というカラムも同時に追加され、レコードの作成日時と更新日時が自動的に設定されるようになっている。
参考
いつもお世話になってます。