読者です 読者をやめる 読者になる 読者になる

気軽に楽しくプログラムと遊ぶ

自分が興味があってためになるかもって思う情報を提供しています。

Rails モデル作成メソッドの実装をscaffoldの実装に近づける

プロゲートで学んだことを理解を深めるために書いていきます。
Progate | プログラミングの入門なら基礎から学べるProgate (プロゲート)

今回は中級 2章の「scaffoldのコードに近付けよう(1)」をやっていきます。

setterを削除する

def create()
  @note = Note.new()
  @note = param[:title]
  @note = param[:content]
  @note.save
end

上記は以下のように書き換える事が可能。
newメソッドは各プロパティを保持するハッシュを受け取り、各プロパティへ設定してくれる

def create()
  @note = Note.new({param[:title], param[:content]})
  @note.save
end

そして、さらにView側でtitleとcontentのName属性を以下のように設定しておくと

< inpute type="text" name="note[title]" />
< inpute type="content" name="note[content]" />

以下のように書き換えることができる。
noteというKeyを保持するハッシュを取得可能。

def create()
  @note = Note.new(param[:note])
  @note.save
end

ただし、param[:note]は悪意のあるユーザーに書き換えられ、予期しない他の属性に 書き換えられる危険性がある。そこでストロングパラメータを用いる。

ストロングパラメータ

これは、指定した要素内には許可した属性しか指定できないようにするもの

def create()
  # requireに対象オブジェクトのキーを設定、許可属性をpermit内に記載
  @note = Note.new(params.require(:note).permit(:title, :content))
  @note.save
end

下記のようにメソッド化するとすっきりかける。

def create()
  @note = Note.new(note_params)
  @note.save
end

private
def note_params
  params.require(:note).permit(:title, :content)
end

バリデーション

バリデーション(入力値チェック)はモデルに設定する

class Note < ActiveRecord::Base
  # titleを入力必須にする
  validates :title, presence: true
  # contentを入力必須に設定。また、最大140文字に入力を制限する
  validates :content, presence: true, length: { maximum: 140 }
end

validatesは複数指定できるので複数系で表現。
第1パラメータにシンボルで属性名。第2パラメータ以降にハッシュでバリデーションを指定。

バリデーション成功後のredirect先の書き方

def create
  @note = Note.new(note_params)
  if @note.save
    # note_pathへ移動。引数に@note.idを指定
    redirect note_path(@note.id)
  end
end

上記の省略した書き方

# @noteのみでも@note.idを表せる
redirect_to note_path(@note)
# これも上記と同じ意味。内部処理でnote_pathへ移動かつ@note.idを引数に指定してくれる。
redirect_to @note

redirect_toはデフォルトでgetのリクエストを送信する。

render

アクションを経由せずにViewを直接呼ぶ。

def create
  @note = Note.new(note_path)
  if @note.save
    redirect_to @note
  else
    render :new # シンボルでview名を指定
  end
end

バリデーションのエラーメッセージを表示する

Noteモデルのerrorsオブジェクト内のメッセージ配列にアクセスしてメッセージを表示する

<% if @note.errors.any? %>
  <h2><%=@note.errors.count %>件のエラーがあります。</h2>   
  <ul>
    <% @note.errors.full_messages.each do | message | %>
      <li><%= messaga %></li>
    <% end %>
  </ul>
<% end %>

ちょっと復習
<% %>は値を返却しない場合に用いる。
<%= %>は値を返却する場合に用いる。