概要
学習内容: データベースのリレーション「n対n」の関係について学習し、特に「いいね」機能を実装するための設計方法を学びました。
学んだ主要な概念やスキル
~1. n対nのリレーションの理解~
複数のユーザーが複数の記事に「いいね」をする関係を実現するためには、n対nのリレーションを理解する必要がある。
例えば、ユーザー1が記事2と記事3に「いいね」し、ユーザー2が記事1に「いいね」するような場合など。
-
中間テーブル(ライクステーブル)の役割
ユーザーと記事の関係を管理するために、中間テーブル(ライクステーブル)を作成する。
例えば、中間テーブルには、ユーザーIDと記事IDが格納され、これによってどのユーザーがどの記事に「いいね」したかが管理される。 -
アクティブレコードの設定
関連付けが必要、has_manyとbelongs_to
の設定を使って、ユーザーと記事の間に「いいね」のリレーションを構築する。
デストロイの依存性についても、dependent: :destroy
を設定することで、ユーザーや記事が削除された際に、それに関連する「いいね」も自動的に削除されるようにする。 -
データベースとアクティブレコードの連携
マイグレーションファイルの作成
rails generate model
コマンドを使って、中間テーブルを含む必要なテーブルやモデルを作成する。
マイグレーションの実行
rails db:migrate
コマンドでデータベースに反映させる。
01 Likeモデルを作ろう
使用したコード
1. Likesテーブルのマイグレーションファイルの作成:
create_table :likes do |t|
t.references :user, null: false
t.references :article, null: false
t.timestamps
end
2.モデルの設定:
has_many :likes, dependent: :destroy
belongs_to :user
belongs_to :article
has_many :likes, dependent: :destroy
02 「いいね」できるようになろう
〜手順の説明〜
1. ルーティング設定:
config/routes.rb
で、記事に対する「いいね」のルーティングを設定。resources :likes, only: [:create, :destroy]
とし、削除を考慮してresources
を使用。
こうすることで、特定のlike_id
を指定せずにlike
を削除可能。
#いいねできるように生成・削除でハート画像が変わる
resource :like, only: [:create, :destroy]
2. コントローラーの作成:
LikesController
を作成し、create
とdestroy
アクションを定義。
create
アクションでは、ログインしているユーザーと対象記事に基づいて「いいね」を作成。
destroy
アクションでは、ユーザーが行った「いいね」を削除。
class LikesController < ApplicationController
before_action :authenticate_user!
def create
article = Article.find(params[:article_id])
article.likes.create!(user_id: current_user.id)
redirect_to article_path(article)
end
def destroy
article = Article.find(params[:article_id])
like = article.likes.find_by!(user_id: current_user.id)
like.destroy!
redirect_to article_path(article)
end
end
3. ビューの調整:
記事の詳細ページで「いいね」ボタンを追加。ログインしているユーザーのみボタンが表示される。
link_to
ヘルパーを使って、「いいね」ボタンをPOSTリクエストとして送信。
いいね済みかどうかに応じて、ボタンの表示を変更するためにUser
モデルにhas_liked?
メソッドを追加。
- .article_heart
- = image_tag 'heart.svg'
+ - if user_signed_in?
+ - if current_user.has_liked?(@article)
+ .article_heart
+ = link_to article_like_path(@article), data: { method: 'delete' } do
+ = image_tag 'heart-active.svg'
+ - else
+ .article_heart
+ = link_to article_like_path(@article), data: { method: 'post' } do
+ = image_tag 'heart.svg'
4. いいねの状態管理:
ユーザーが既に「いいね」しているかどうかを確認し、している場合はボタンを赤色に変更。
いいねされている場合は、has_liked?
メソッドを使って、if
文で表示を切り替える。
5. いいねの解除:
いいねしたボタンを再度押すと、その「いいね」が解除されるように実装。
6.最終確認:
実際にブラウザ上で動作を確認し、いいねが正常に機能しているかを確認。
7. セキュリティと利便性:
like_id
を直接操作せず、ユーザー自身が行った「いいね」だけを削除できるようにすることで、他のユーザーの「いいね」を誤って削除できないようにしている。
03.「いいね」の数を表示する
「いいね」のカウント:
- 「いいね」の数をカウントするためには、
Rails
のActiveRecord
のcount
メソッドを使うと便利です。 -
likes.count
で、「いいね」の数を取得できます。 - 例えば、特定のアーティクルに対する「いいね」の数が1や0になる様子を確認することができます。
def like_count
likes.count
end
%span= article.like_count
アクションを定義:
class FavoritesController < ApplicationController
#ユーザーがログインしている状態か確認
before_action :authenticate_user!
def index
#お気に入りした記事を取得
@articles = current_user.favorite_articles
end
end
自分が「いいね」した記事の表示:
- 自分が「いいね」した記事だけを表示するためのページを作成します。
-
has_many :through
の関連付けを使って、「いいね」した記事を取得します。 - モデル内で
has_many :favorited_articles, through: :likes, source: :article
と設定します。 - これにより、ログインユーザーが「いいね」した記事を取得し、表示することができます。
#中間テーブルを通して自分がいいねした記事の情報を取得している
has_many :favorite_articles, through: :likes, source: :article
``
#### ビューの作成:
- いいね」した記事を表示するビューを作成します。
- `app/views/favorites/index.html.erb`に表示する内容を記述し、ユーザーが「いいね」した記事の一覧を表示します。
- リンクを追加して、他のページと連携するようにします。
```ruby:views/favorites/index.html.haml
.container
%h2
お気に入りの記事
- @articles.each do |article|
= render 'commons/article', article: article
ついでにロゴURLをつける
- %p.header_pageTitle B-log-app
+ %p.header_pageTitle
+ = link_to 'BlogApp', root_path
05.アイキャッチの設定
😺 さあ、この日最後の授業だにゃん!
🦊 やっていいこう!
画像のアップロードと表示の機能を追加する手順が解説されました。
Active Storageの復習と設定:
まず、アーティクルモデルで画像アップロード機能を追加します。画像を1つだけアップロードする場合はhas_one_attached
を、複数の場合はhas_many_attached
を使用します。
コントローラーの設定:
アーティクルコントローラーで、画像を許可するパラメーターを設定します。
ビューの設定:
ビューでフォームにファイルアップロード用のフィールドを追加し、ユーザーが画像をアップロードできるようにします。
画像の表示:
アップロードされた画像を表示するためのコードを追加します。詳細ページ(ショーアクション)でも画像が表示されるようにし、画像が大きすぎる場合はCSSでサイズを調整します。
動作確認:
画像のアップロードが正しく機能しているかを確認し、新規作成や編集時にも画像が表示されることを確認します。
次回予告:
次回は、このアプリケーションを公開するための準備について説明する予定です。