0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】アソシエーションを使ってみる

Posted at

#はじめに
現在独学で未経験からWebプログラマーを目指しているものです。アウトプットとして記事を書いています。初学者の方にお役に立てれば幸いです。
#なぜアソシエーションを使うのか
アソシエーションとはモデル同士の関連付けを行うために必要となるものです。
Twitterなどでは一人のユーザーが1つまたは多数の投稿を行なっています。例えばuser1というユーザーがtweet1という投稿を行なったとします。アソシエーションを使わなかった場合、tweet1を投稿したユーザーのモデルに格納されているemailなどのデータを取り出したいときに大変厄介になってしまいます。
アソシエーションはこのモデル間にキーを設けることにより関連性を持たせることができます。

aso1.jpeg

#関連付けの種類について
アソシエーションを使うことで各モデル間に関係性を持たせることができることがわかりました。ところで前述で書いたuser1はたくさんのtweetを保有しています。また、tweet1user1に属しているものとして考えられます。この関係性からuser1が親tweet1が子の関係であるといえます。親子の関係性は今後重要になってきます。

##1.1対1
アソシエーションの種類は3通りあります。まず1対1について紹介します。これはユーザー1人に対しアイコン画像1つが対応するときなどに使う関連付けです。
まずログイン機能をつけるものとし、deviseでUserモデルを管理したいと思います。
Gemfileに以下を記述します。

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行を追加します。

app/models/user.rb

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を使います。

app/models/image.rb

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モデルは複数形にします。

app/models/user.rb

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と同様です。

app/models/tweet.rb

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をもっていると考えられるので、

app/models/user.rb

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 #追加
app/models/tweet.rb

class Tweet < ApplicationRecord
  belongs_to :user 
  has_many :favorites #追加
end

Favoriteモデルは子なので

app/models/favorite.rb
class Favorite < ApplicationRecord
    belongs_to :user
    belongs_to :tweet
end

となります。

#まとめ

  • 従属関係(親、子)の関係を決める
  • 親のモデルでは、1対1のときはhas_oneメソッド、1対多と多対多はhas_manyメソッドを使う
  • 子のモデルではbelongs_toメソッドを使う

#参考
【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?