Doiya’s blog

日々の進捗を書く雑記ブログ(メインはエンジニアやプログラミング関連)

現場Rails 写経で得た事(4章) 後編

とりあえず、自分が特に学んだものを列挙していきます。

1 モデルの仕組み Railsにおけるモデルの検証は基本的に「モデルオブジェクト(レコード)をデータベースに登録・更新する前に検証を行い、エラーがあれば登録・更新をしないで差し戻す」と言う仕組みになっています。 saveメソッド:データベースの登録更新を行う前に自動で検証する。エラーがあればfalseを返す。詳細はerrorsでわかる。この時、検証失敗以外の予期せぬエラーがあれば、例外を発生する。 save!メソッド:検証エラー時にfalseを返すのではなく例外を発生させるメソッドです。 valid? :検証処理単独で呼ぶ。 00.errors.full_messages: 完成された検証エラーメッセージの形

2 必要なデータが入っているか?

validates :○○, presence: true

3 以下の文章の流れ

def create
   @task = current_user.tasks.new(task_params)  ③

   if @task.save ①
     redirect_to @task, notice: "タスク「#{@task.name}」を登録しました。"
   else
     render :new ②
   end
  end

一 登録のために用いるメソッドの変更です。今回、name属性が入っていなくてはならないという検証を追加したので、ユーザーの入力次第では、検証エラーによって登録が失敗するようになりました。そこで、save!ではなくsaveを使うようにしてそも戻り値によって制御を変える。 二 検証エラーの時の処理の追加です。検証エラーがfalseだった時はrender:newによって、登録用のフォーム画面を再び表示して、ユーザーに再入力 を促しています。 三 Taskオブジェクトを@taskというインスタンス変数に代入するようにしていることです。これは、検証エラーがあってもう一度新規登録画面を表示する際に、ビューに検証を行った現物のTaskオブジェクトを渡す必要があるから。 @taskをビューに伝えることによって、次の2点の効果が生まれる。 三の一 Taskオブジェクトには直前にユーザーがフォーム送信したデータが入っているため、前回操作したままの値をフォーム内に引き継いで表示できます。もしこれを行わないと、検証エラーが発生するたびに全てのデータを新たに入力しなおす必要がある。ユーザーがイライラするらしい。 三の二 Taskオブジェクトのかかえる検証エラーの内容をユーザーにして表示する。 三の三 以下の文でエラーメッセージが出る。

- if user.errors.present?
 ul#error_explanation
  -user.errors.full_messages.each do |message|
   li = message

4 ユーザーのパスワードをdigestを生成・保存。 has_secure_password

password: ユーザーが入力した生のパスワードを一時的に格納するための属性です。 password_confirmation 確認パスワードを一時的に保存する。

5 ログイン画面を表示するためのアクションに対してもlogin_requiredフィルタが実行されて、どのURLをリクエストしても、無限にredirectしないための対策で以下の一文を加える。

sessions_controllers.rb

skip_before_action:login_required

6 ログインしているユーザーに紐づくTaskだけを表示する。

@tasks = current_user.tasksイコール@tasks = Task.where(user_id: current_user.id)

7 最初の管理ユーザーを作る時 bin/rails c で以下の一文やるか、seed(初期データを投入するやり方)を利用する。

User.create!(name: , email: ,password: ,password_confirmation: ,admin: true)

8 現場rails p176 p177は復習しましょう!

9 URLをリンクとして表示する方法 ・gem 'rails_autolink'をインストールする。 ・tasks/show.html.slimを以下のようにする。

td= auto_link(simple_format(h(@task.description), {}, sanitize: false, wrpper_tag: "div"))