学習記録

アウトプット用に作りました

findとfind_by

find

各モデルをidを検索キーとしてデータを取得するメソッド。
id以外の条件で検索不可。

存在しないユーザーを指定すると、例外が発生する。
(ActiveRecord::RecordNotFound)

User.find(1)


find_by

各モデルをid以外で検索するメソッド。
idでも検索可能。
複数の検索条件指定可能。

存在しないユーザーを指定するとnilが返る。

User.find_by(email: "user@example.com")

authenticateメソッド

authenticateメソッドは、
has_secure_passwordメソッドをユーザーモデルで呼び出すだけで使えるようになるメソッド。

authetnticateメソッドはパスワードを引数として使う。
誤ったパスワードを渡されるとfalseを返す。
正しいパスワードを渡されるとtrueを返す。

user&.authenticate(session_params[:password])  

なんでここで&.(ぼっち演算子)を使ってメソッドを呼び出すのか?
→レシーバー(user)がnilでも、NoMethodErrorが出ないでnilを返すことができるから。

もしここでぼっち演算子を使わないと、
フォームにパスワードが格納されずに送られた場合、エラーが出てしまう。
(パスワードがnilだったらfalseの扱い)

def create
  user = User.find_by(email: session_params[:email])

  if user&.authenticate(session_params[:password])  
    session[:user_id] = user.id
    redirect_to root_url
  else
    render :new
  end
end

送られてきたメールアドレスでユーザーを検索する。
ユーザーが見つかったら、送られてきたパスワードを使ってメールアドレスとパスワードが一致するユーザーを探す。
一致するとセッションにuser_idを格納してroot_urlへ飛ぶ。
一致しない = falseかnilが返るとnewにレンダリングされる。

パーシャル

パーシャルを使う目的は、viewの一部を別のファイルに切り出し、 同じ部分を持っているviewのコードを共通化してメンテナンスをしやすくする。

パーシャルファイルはファイル名の先頭にアンダースコアをつける。
例えばこのようなファイル名にする。_form.html.slim

このパーシャルテンプレートを呼び出すときは、renderを使う。

render 'form'

render ファイル名 で呼び出すことができる。

namespace

namespace

namespaceを使うとURLを新しく指定して、新たに作ったアクションにリクエストが飛ぶようになる。
管理画面のルーティングを作るときに用いられる。


rails generate migration ファイル名を使ってadmin用のマイグレーションファイルを作る。
7つの基本的なアクションが作られる。

rails generate controller Admin::Users getアクション名を使ってコントローラを作る。


マイグレーションファイルとコントローラを作ったら、ルーティングを定義する。

namespace :admin do
  resources :users
end

この結果、admin/usersというURLが送られると、adminのusersコントローラのindexアクションに飛ぶ。

get '/admin/users', to: 'admin/users#index'


他にもよく似たscope、scope moduleがある。
scopeはURLだけを新たに指定することができる。
scope moduleはURLは変えずに、新たに作ったアクションにリクエストが飛ぶようになる。

rails generate

rails generateコマンドで生成されるファイルを把握していなかったので、簡単にまとめておく。

rails generate model User name:string

Userモデルを作って、nameカラムを作成する

生成されるファイル
* モデル
* マイグレーション
* テスト

rails generate migration ChangeTasksNameNotNull

tasksテーブルのnameをnull不可にする
テーブルのカラムの内容を変更するときに使う。
ファイルの名前は何を変えるのかわかりやすい名前にする。

生成されるファイル
* マイグレーション
* テスト

rails generate controller tasks index show

indexとshowのアクションを追加する

生成されるファイル
* コントローラ
* ビュー
* アセット
* ルート
* テスト
* ヘルパー

scope

繰り返し利用される絞り込み条件を読みやすくすることができる。

絞り込み条件とは

クエリー(SQLを実行したときにデータベースに送る命令文)のメソッドを使って、データベースのデータを絞り込むときに使う。

(例) Userのidを降順にして5つデータを表示する。

User.order(id: desc).limit(5)


scopeを使う

上記のメソッドを使ったデータはカンマでたくさん区切ってあって、
重複しているところに何度も同じコードを書くのも面倒で、コードを読むのも大変。
なのでscopeを使って書き換えてみる。

models/user.rb

  scope :recent, -> { order(id: :desc).limit(5) }

users_controller.rb

def index
  @users = User.recent
end

recentにクエリーの情報が含まれてメソッドとして使えるから、
コントローラーで複数のクエリーを書かなくて済む。

renderとredirect_toの使い分け

render

別のアクションを経由せずに、直接ビューを表示する。

使用目的 : エラーなどで処理が正常に完了せず、元の画面に戻したいだけの時に使用する。

def create
  render :new     # 表示するviewファイルを指定
end

→ 登録に失敗したら、新規登録画面を表示する。

controller → view
(createアクション) → (新規登録画面)


redirect_to

他のURLに転送する。

使用目的 : データの追加(create)、更新(update)、削除(destroy)をしたいときに使用する。

def create
  task = Task.new(task_params) 
  task.save!
  redirect_to tasks_url
end

→ 登録画面で入力されたデータがデータベースに保存されて、一覧画面(tasks_url)に移動する

controller → URL → route → controller → view
(createアクション) → (HTTPリクエストを受け取る) → (リクエストを処理) → (indexアクション) → (一覧画面)


※ render、redirect_toを記述しないと、renderで処理される。(renderは省略可)


登録が成功するとき(データベースに変化があるとき)は、redirect_toを使う。
この認識でいいのかな〜。。