Railsのアソシエーションの設定方法は??

Railsアプリを作っていると、複数のモデルを取り扱わねばなりません。

そこでマスターしておきたいのは、

アソシエーション

です。複数のモデルの関連付けを指す用語。

アソシエーションを設定すれば、「あるデータ」と関連する「別のデータ」を取得できるのです

 

例えば、tweetsusersという2テーブルがあったとしましょう。

アソシエーションを設定すれば、

  • あるuserがつぶやいたtweetを取得
  • あるtweetをつぶやいたuserの名前を取得

をできるようになります。

つまり、テーブルの垣根を飛び越えて値を取得できるのですね。

 

TECH::CAMPでアソシエーションを習った時は、

  • has_many
  • belongs_to

を使うと学んできました。

しかし、最近勉強したプロゲートで紹介されていたのは、これらに頼らない原始的な方法。

僕的にはこちらの方法がしっくりきました。

 

アソシエーションには色々なパターンがありますが、僕がマスターしたのは

  • 1対1
  • 1対多

の2パターンです。

 

1対1のアソシエーション

まず1対1のアソシエーション。

ある1つのデータに紐づくデータが1つの関連付けです。

 

例えば「tweet_1をつぶやいたuser情報」を取得したい時ですね。

あるtweet_1をツイートしたuserは1人しかいません。

ゆえに、1tweetに対して1userで「1対1の関係」になっているわけです。

 

例えば、user・tweetモデルだったらtweetモデルファイルを次のように編集します。

class Tweet < ApplicationRecord

def user
  return User.find_by(id: self.user_id)
end
	
end

ポイントはfind_byメソッドの引数self

selfは記述されているモデルのオブジェクト「tweetモデル」を表わしています。

self.user_idとすれば、該当するtweetモデルを取得できますね。

このように編集しておけば、

tweet.user.name

とすれば、tweetしたuser名を取得できるでしょう。

 

1対多のアソシエーション

「1つのデータ」が「複数のデータ」を持っている場合。

例えば、user_1がつぶやいたtweetをすべて取得したい時で、tweetは1つではなく、複数の可能性もあります。

Twitterでつぶやきまくっている人もいますから。

 

つまり、userとtweetの関係は「1対多」。

次のようにモデルファイルを編集しましょう。

class User < ApplicationRecord
	
 def tweets
   return Tweet.where(user_id: self.id)
 end
end

 

1つのデータに対して、複数紐付いているデータがあるので、find_byメソッドではなく、whereメソッドを使います。

これで複数のデータを「配列」で取得できますね。

 

例えば、user.tweetsとすれば、あるuserに紐付いたtweetを配列で取得できるのです。

配列をeachメソッドで展開してやれば、それぞれ内容をビューファイルで表示できますね。

 

以上です。

ぼく自身、has_manybelongs_toに頼らないアソシエーションがしっくりきました。

なんというか、ブラックボックス状態にせず、中身をしっかり理解できましたから。

Railsアプリを作ったらアソシエーションの設定もしてみてください。

 

それでは!

Lin