はじめに
Ruby on Railsチュートリアルの備忘録
チュートリアル学習者向けに書いています。
あとは備忘録
14章の内容です。この章は、モデル設計を理解するのが1番の重要で、これさえ理解できれば消化試合です。
チュートリアルと合わせてご覧ください。
migration生成
# referencesは使わない
# user_id:referenceだとuser_id modelを探しに行く挙動
rails generate model Relationship follower_id:integer followed_id:integer
class CreateRelationships < ActiveRecord::Migration[6.0]
def change
create_table :relationships do |t|
t.integer :follower_id
t.integer :followed_id
t.timestamps
end
# 総フォロー数やフォロワー数はよく問い合わせるのでindex
add_index :relationships, :follower_id
add_index :relationships, :followed_id
# 下記は一意生のために必要。
# フォローボタンを連打してもAがBをフォローは必ず1つになる
add_index :relationships, [:follower_id, :followed_id], unique: true
end
end
has_many
has_many
はメソットを作るためのメソットである
Userモデル
class User < ApplicationRecord
# UserのidとMicropostのuser_idを紐づける
has_many :microposts, dependent: :destroy
# Default: class_name : "Micropost"
# Default: foreign_key: "user_id"
# UserのidとRelationshipのfollower_idを紐づける
# active_relationshipsメソッドを作成(自身[が]フォローしてるrelationshipデータを全て取得)
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
# Defaultではない設定
# class_name : Relationship
# foreign_key: follower_id
# @user.active_relationships.buildと
# すると自動的にfollower_idにuserを設定
belongs_to
Relationshipモデル
class Relationship < ApplicationRecord
# Relationshipのfollower_idとUserのidを紐づける
# followerメソッドを生成(そのデータのフォローしているuserを特定)
belongs_to :follower, class_name: "User"
# foren_key: follower_id
# class: User
# Relationship.first.followerが使える
# DefaultだとclassはFollowerになってしまう
belongs_to :followed, class_name: "User"
# Relationship.first.followedが使える
end
バリデーションを追加
テストを書くならgenerate
で自動生成されたfixture
を削除
app/models/relationship.rb
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
validates :follower_id, presence: true
validates :followed_id, presence: true
has_many through
上記のhas_manyやbelong_to
を実装したことで下記実装を行える
user.followingを作成(フォロー)
app/models/user.rb
class User < ApplicationRecord
.
.
# following メソッドを生成する(フォローしている人を全て特定する) @user.following
# Userインスタンスにactive_relationshipsメソッドを実行 (自身[が]フォローしているrelationshipデータを全て取得)
# 得られたdata1つ1つにfollowedメソッドを実行(誰をフォローしているのか特定)
has_many :following, through: :active_relationships, source: :followed
.
.
end
------------------------------------------------------------
# 関連づけをしたことによりフォローしているユーザーを配列のように扱うことができる
user.following.include?(other_user)
user.following.find(other_user)
# followingで取得したオブジェクトは、配列のように要素を追加したり削除したりすることができる。
user.following << other_user # 配列の最後に追記
user.following.delete(other_user)
user.followersを作成(フォロワー)
app/models/user.rb
class User < ApplicationRecord
.
.
# UserのidとRelationshipのfollowed_idを紐づける
# passive_relationshipsメソッドを作成(自分[を]フォロー全てのrelationshipデータを取得)
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :followers, through: :passive_relationships, source: :follower
.
.
end
便利メソッドを作成する
app/models/user.rb
# ユーザーをフォローする
def follow(other_user)
following << other_user
end
# ユーザーをフォロー解除する
def unfollow(other_user)
active_relationships.find_by(followed_id: other_user.id).destroy
end
# 現在のユーザーがフォローしてたらtrueを返す
def following?(other_user)
following.include?(other_user)
end
これ以降はrails tutorial 14章を参照