学習の書き留め プログラミング勉強中

プログラミングで学んだことを日記として残して行こうと思います

今日の学習

今日学んだこと 2020/12/27

学習項目

  1. 投稿者本人のみに編集・削除を許可する
  2. 表示順の並び替え
  3. 複数ページで利用する表示の一部をまとめる
  4. ルーティングのネストについて
  5. パラメーターについて

学習内容

投稿者本人のみに編集・削除を許可する

実装方法

編集、削除のアクションに紐付くlinkに対してif文を入れる。
条件式の内容を投稿内容のidログイン中のid同一の時のみ表示するという内容にする。

<% if user_signed_in? && current_user.id == モデル.user_id %>
<%= link_to '編集又は削除', 'url' method ':HTTP-method' %>
<% end %>

user_signed_in?メソッド
Gemのdeviseを導入していると、使用できるメソッド。
ログインしているかどうかの判定を行う。
user_signed_in?メソッドは、ユーザーがログインしていればtrueを、ログアウト状態であればfalseを返す。

current_userメソッド
Gemのdeviseを導入していると、使用できるメソッド。 current_userは、現在ログインしているユーザーの情報を取得する。

上の条件式でログインをしていて、かつ、操作しようとしている投稿が自分の投稿の場合のみ編集と削除につながるアクションが表示されるようになる。

表示順の並び替え

レコードの取得順を変更する

並び替える方法は、表示のときに順番を変えるのではなく、情報を取得するタイミングで先に並び替える。

orderメソッド
モデルが使用できるActiveRecordメソッドの一つ。
テーブルから所得してきた複数のレコード情報を持つインスタンスの、並び順を変更するメソッド。
引数には"並び替えの基準となるカラム名 並び順"のように「並び替えの基準となるカラム名」と「並び順」を半角スペースで繋げて指定する。
使用方法 複数のレコード(列)情報を取得する文に続けて以下のように記述。

インスタンス = モデル名.order("並び替えの基準となるカラム名 並び順")

並び順にはそれぞれAscending/Descendingの略でASC(昇順)とDESC(降順)の2種類。

並び順 内容
ASC(昇順) 小さいものから大きいものになる。古いものから新しいのものになる
DESC(降順) ASCの反対

複数ページで利用する表示の一部をまとめる

部分テンプレートの使用法

rails では同じコードを何度も使用する場面がある。例えば、Twitterでは新規投稿と編集のhtmlは同一のものが使用されている。
こう言った部分は別のファイルに切り出し管理をしやすくするのが好ましい。
こういった部分的にビューファイルにおいて繰り返し使用するコードを切り出し、再利用する仕組みのことを部分テンプレートという。

_◯◯.html.erbファイル
部分テンプレートとして切り出す際に作成するファイル。 命名規則として、アンダースコア_を先頭に記述する。

renderメソッド
部分テンプレート(_◯◯.html.erbファイル)を呼び出す際に利用する。
呼び出すファイルの指定や、部分テンプレート内で変数を使用したい場合はオプションで指定する。

オプション
partialオプションで呼び出すテンプレートを指定する。
異なるディレクトリ内の部分テンプレートを呼び出すときはsamples/sampleのように、どのディレクトリの部分テンプレートを使用しているかを明示的に記載する
localsオプションは部分テンプレート内でその変数を使えるようにする。

<% render partial: "sample", locals: { post: "hello!" } %>
適用方法
1. 添付するファイル(例:` _sample.html.erb `)を作成
2. 切り出したあと1のファイルに添付
3. 切り出されたファイルに
<% render partial: "sample", locals: { post: "hello!" } %>
  と記述

ルーティングのネストについて

通常、コメントだけをデータベースに保存する際、ルーティングには

post 'comments', to: 'comments#create'
resources :comments, only: :create

のどちらかを記載するはず。
とはいえ、TwitterInstagramではそれぞれの投稿に対してコメントができる。このコメントの実装には誰がどの投稿にコメントを残したのかをわかるようにしなければならない。
その統合自体はアソシエーションで行う事ができるのだが、ルーティングの設定にはひと工夫必要になる。
今日はそのルーティーンのひと工夫(ネスト)について学んだ。

ルーティングのネスト

まず、そもそもネストとは、ある記述の中に別の記述をして、親子関係を示す方法。「入れ子構造」とも呼ばれる。
ルーティングにおけるネストは、あるコントローラーのルーティングの中に、別のコントローラーのルーティングを記述することをいう。

Rails.application.routes.draw do
  resources :親となるコントローラー do
    resources :子となるコントローラー
  end
end
ネストの有無による比較

ネストを利用した場合

Prefix Verb           URI Pattern                            Controller#Action
sample_comments POST   /samples/:sample_id/comments(.:format)   comments#create

ネストを利用しなかった場合

Prefix Verb     URI Pattern           Controller#Action
comments POST   /comments(.:format)   comments#create

上を見てわかるように、ネストを利用するとその投稿に対して処理をするルーティングが作られる。

パラメーターについて

アプリケーションでは、ブログの文字データやinstagramの画像データなどさまざまなデータを私たちから受け取っている。今日はその外部から送れれてくるデータの使用方法についてまとめる。

外部から送られるデータ

パラメーター

リクエスト(ユーザーが要求すること)に含まれてサーバーの外部から渡されるデータ。
URLに含めるパラメーターやフォームから送信されるパラメーターがある。
Railsのパラメーターはparamsに格納されてコントローラーに届けられる。

params

送られてきたパラメーターをハッシュのような構造で格納したもののこと。
フォームで送信されたデータもparamsの中に格納されてコントローラーで受け取られる。
例えば

model sample_a
<%= form_with(model: @sample, local:true) do |form| %>
<%= form.text_field :sample %> # "さんぷる"と入力
<%= form.text_field :name %> # "みんてぃ"と入力
<%= form.text_area :text %> # "お疲れさま"と入力
<%= form.submit "SEND" %>
<% end %>

こういった形で、送信したとする。
すると、paramsに{sample: さんぷる, ...}といったハッシュのような構造で格納される。
コントローラーでparams[:sample]と記述すると、「さんぷる」というデータを取り出すことができる。

受け取るデータの制限

先程のデータはsample name textと複数のキーを持っている。コントローラでキーを受け取る際、欲しいものだけ受け取れるように制限をかけることで意図しないデータの更新を防ぐ事ができる。

ストロングパラメーター

ストロングパラメーターは、指定したキーを持つパラメーターのみを受け取るように制限するもの。
ストロングパラメーターの定義にはrequireメソッドpermitメソッドを組み合わせて使用する。

requireメソッドとpermitメソッド

requireメソッドは送信されたパラメーターの情報を持つparamsが、使用できるメソッド。パラメーターからどの情報を取得するか選択できる。
ストロングパラメーターとして使用する場合は、主にモデル名を指定する。
permitメソッドもparamsが使用できるメソッド。
permitメソッドを使用すると、取得したいキーを指定でき、指定したキーと値のセットのみを取得する。

params.require(:モデル名).permit(:キー名, ...)
params.require(:sample_a).permit(:name, :text)
#=> { "name" => "みんてぃ", "text" => "お疲れさま" }

こうする事でsample_bというmodelがあったりや、他に送られてきたデータがあったとしても、欲しい情報のみ受け取る事ができる。

ストロングパラメータは、メソッドとして定義するが、コントローラのプライベートメソッドとして定義する。

プライベートメソッド

クラス外から呼び出すことのできないメソッドのこと。
Rubyでは、privateと記述した以下のコードがプライベートメソッドになる。

class Sample_AController < ApplicationController
  def new
    @sample = Sample_a.new
  end

  def create
    Sample_a.create(sample_params)
  end

  private  # private以下の記述はすべてプライベートメソッドになる

  def sample_params  # プライベートメソッド
    params.require(:sample_a).permit(:name, :text)
  end
end
プライベートメソッドのメリット
  1. Classの外部から呼ばれたら困るメソッドを隔離 プライベートメソッドはClass外から呼び出すことが不可能のため、誤って呼び出してしまう等によるエラーを事前に防ぐことができる。

  2. 可読性 繰り返し使用するメソッドもprivate以下に集約する事で、コードをシンプルにできる。

複数の情報をまとめる

基本的なparamsは上記の通りなのだが、例えばTwitterでは、ユーザーの情報とツイートの情報は別々のテーブルに保存されている。こういった場合は情報を結合させる必要がある。mergeメソッドを使い、情報を一つにする。

mergeメソッド

ハッシュを結合させるときに使用するRubyのメソッド。
2つのハッシュを1つにまとめることができる。

sample = { name: "みんてぃ", text: "お疲れ様さま" }
sample_id = { user_id: "1" }
tweet.merge(sample_id)
#=> {:name=>"みんてぃ", :text=>"お疲れ様さま", :user_id=>"1"}

まとめ

たくさん頑張った!