#はじめに
現在独学で未経験からWebプログラマーを目指しているものです。アウトプットとして記事を書いています。初学者の方にお役に立てれば幸いです。
#なぜアソシエーションを使うのか
アソシエーションとはモデル同士の関連付けを行うために必要となるものです。
Twitterなどでは一人のユーザーが1つまたは多数の投稿を行なっています。例えばuser1というユーザーがtweet1という投稿を行なったとします。アソシエーションを使わなかった場合、tweet1を投稿したユーザーのモデルに格納されているemailなどのデータを取り出したいときに大変厄介になってしまいます。
アソシエーションはこのモデル間にキーを設けることにより関連性を持たせることができます。
#関連付けの種類について
アソシエーションを使うことで各モデル間に関係性を持たせることができることがわかりました。ところで前述で書いたuser1はたくさんのtweetを保有しています。また、tweet1はuser1に属しているものとして考えられます。この関係性からuser1が親、tweet1が子の関係であるといえます。親子の関係性は今後重要になってきます。
##1.1対1
アソシエーションの種類は3通りあります。まず1対1について紹介します。これはユーザー1人に対しアイコン画像1つが対応するときなどに使う関連付けです。
まずログイン機能をつけるものとし、deviseでUserモデルを管理したいと思います。
Gemfileに以下を記述します。
gem 'devise' #追加
bundle installします。
$bundle install
次にdeviseのインストールとUserモデルを作成します。
$rails g devise:install
$rails g devise User
Userモデルに対応する画像モデルはImageとします。
$rails g model Image user_id:integer
$rails db:migrate
ここで重要なのはuser_id:integerをカラムとして追加している点です。最初にモデル間の関係を持たせるにはキーが必要だといいました。なので**(モデル名)_id**という形でカラムを追加しておきましょう。
ここからアソシエーションの機能をつけていきます。ImageモデルがUserモデルに従属している、つまりUserが親、Imageが子の関係であるためここでは、親のUserモデルにはhas_oneを利用します。Userモデルに下記の1行を追加します。
class Account < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one :image #追加
また従属している側のImageモデルにはbelongs_toを使います。
class Account < ApplicationRecord
belongs_to :user #追加
end
##2.1対多
ユーザー1人が多くのtweetを投稿するときなどには1対多のアソシエーションを利用します。
まずTweetモデルを作ります。Imageと同様にuser_id:integerを追加します。
$rails g model Tweet body:text user_id:integer
$rails db:migrate
1対1はhas_oneを利用したのに対し、1対多ではUserがたくさんのTweetを保有することになるためhas_manyをUserモデルに追加します。子のTweetモデルは複数形にします。
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one :image
has_many :tweets #追加
Tweetモデルには1対1と同様です。
class Tweet < ApplicationRecord
belongs_to :user #追加
end
##3.多対多
いいねやコメント機能の実装などに必要となります。多対多ではお互いがどのUserがどのTweetにいいねをしたかを整理するために、中間テーブルを作成する必要があります。これによりUser1がいいねしたTweetの数、Tweet1がどれくらいのUserからいいねされたかを把握することができます。
まず中間テーブルFavoriteモデルを作成します。
$rails g model Favorite user_id:integer tweet_id:integer
$rails db:migrate
Userモデル、Tweetモデルは多くのFavoriteをもっていると考えられるので、
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one :image
has_many :tweets
has_many :favorites #追加
class Tweet < ApplicationRecord
belongs_to :user
has_many :favorites #追加
end
Favoriteモデルは子なので
class Favorite < ApplicationRecord
belongs_to :user
belongs_to :tweet
end
となります。
#まとめ
- 従属関係(親、子)の関係を決める
- 親のモデルでは、1対1のときはhas_oneメソッド、1対多と多対多はhas_manyメソッドを使う
- 子のモデルではbelongs_toメソッドを使う