自分用のアウトプット。
昨日の最後、別なページに飛んじゃうっていうのはカリキュラムの途中だったからそうなってるだけで、その後進めていったら普通に修正作業があったので特に問題なし!
N+1問題 … アソシエーションを利用するとデータベースへのアクセス回数が多くなり、アプリケーションのパフォーマンス低下につながるというもの。(ツイートの回数だけデータベースへアクセスをすることになってしまう)
N+1問題の回避
includesメソッド … 引数に指定された関連モデルを一度のアクセスでまとめて取得できる。
モデル名.includes(:紐付くモデル名) と記述。
tweets_controller.rbを編集して、tweetsテーブルとuserテーブルを紐付ける。
tweetsテーブルからstring型のnameカラムを削除する
rails g migration RemoveNameFromTweets name:string
「ユーザーがログインしている」かつ「投稿したユーザーである」場合のみに編集・削除を許可するようにする。
<% if user_signed_in? && current_user.id == tweet.user_id %>
(編集ボタン・削除ボタンを記述)
<% end %>
ツイートが、現在は古い順に並んでいる(新しいツイートが下に追加される)が、順番を変えて新しいものが上に来るようにする。
orderメソッド … モデルが使用できるActiveRecordメソッドの一つで、テーブルから取得してきた複数のレコード情報を持つインスタンスの並び順を変更する。
インスタンス = モデル名.all.order(“並び替えの基準となるカラム名 並び順”)
ASC(昇順)… 小→大、古→新 の順にする
DESC(降順)… 大→小、新→古 の順にする
複数のページで同じ表示を使うものは、各ページに記述するのではなく部分テンプレートを使う。
部分テンプレート … ビューファイルにおいて繰り返し使用するコードを切り出し、再利用する仕組みのこと。
ファイル名は「_◯◯.html.erb」とする。
renderメソッド … 部分テンプレートを呼び出すためのメソッド。
partialオプション … renderメソッドで使用できるオプション。どの部分テンプレートを使うかを指定する。
localsオプション … renderメソッドで使用できるオプション。部分テンプレート内で使える変数を定義できる。
例)_sample.html.erbという部分テンプレートを使い、その中でHello!という文字列の代入されたpostという変数を使えるようにする
<% render partial: “sample”, locals: { post: “Hello!” } %>
ツイートにコメントを投稿できるようにする。
コメントは、ツイートとは別のテーブルで管理する。
userモデルとtweetモデルにアソシエーションを組む。
commentモデルを作成し、マイグレーションファイルを編集。
t.integer :user_id ←誰が投稿したか
t.integer: :tweet_id ←どのツイートに対しての投稿か。
t.text :text ←投稿内容
という3行分(カラム)を追加。
user has many tweets
tweet belongs to user
comment belongs to tweets
comment belongs to users
tweet has many comments
user has many comments というアソシエーション
ネスト … ある記述の中に別の記述をして、親子関係を示す方法。(入れ子構造)
routes.rb を編集
resources :tweets do
resources :comments, only: :create
end
rails routes で確認すると
tweet_comments POST /tweets/:tweet_id/comments(.:format) comments#create
となっている。
コメント投稿時、コメントを保存した後にコメント投稿完了の画面へ飛ぶのではなく、コメントしたツイートの詳細画面へリダイレクトするようにする。
comments_controller.rb を編集
def create
comment = Comment.create(comment_params)
redirect_to “/tweets/#{comment.tweet.id}”
end
※リダイレクト先の指定は、アソシエーションを利用してcommentと結びつくツイートのidを記述。
未ログイン状態ではコメント投稿フォームを出さずにテキストを表示させるためif文を使う。
<% if current_user %>
(投稿フォームの内容)
<% else %>
(ログインしないと投稿できませんよという旨のテキスト)
<% end %>
ツイート検索機能の実装
collection、member … ルーティングを設定する時に使用できる。これを使用すると、生成されるルーティングのURLと実行されるコントローラーを任意にカスタマイズすることができる。
collectionはルーティングに:idがつかない。
memberはルーティングに:idがつく。
今回のような検索機能では、詳細ページのような:idを指定して特定のページに行く必要は無いので、collectionを使う。
ルーティングを編集
collection do
get ‘search’
end
ビジネスロジック … データに対する処理などを行うプログラム処理。
whereメソッド … モデルが使用できるActiveRecordメソッドの一つ。
モデル.where(条件) のように引数部分に条件を指定すると、テーブル内の「条件に一致したレコードのインスタンス」を配列の形で取得する。
引数の条件には「検索対象となるカラム」を必ず含める。
Tweet.where(‘id < 3’) とすると、idが3未満のtweetsテーブルのインスタンスを配列で取得する。
LIKE句 … 曖昧な文字列の検索をするときに使用する。whereメソッドと一緒に使う。
曖昧文字列
% … 任意の文字列(空白文字列含む)
_ … 任意の1文字
実行例
where(‘title LIKE(?)’, “a%” … aから始まるタイトル
where(‘title LIKE(?)’, “%b” … bで終わるタイトル
where(‘title LIKE(?)’, “%c%” … cが含まれるタイトル
where(‘title LIKE(?)’, “d_” … dで始まる2文字のタイトル
where(‘title LIKE(?)’, “_e” … eで終わる2文字のタイトル
テーブルのやりとりに関するメソッドはモデルに置く。
うーむ、ずらずらと書き並べたはいいものの、3割くらいしか理解できてない気が。
カリキュラムをずんずん進めていっただけなので、しっかり復習の時間をとらないといかんね。