LoginSignup
10
6

More than 5 years have passed since last update.

has_many through のアソシエーションに条件を追加する

Last updated at Posted at 2017-03-14

前提

単一テーブル継承 を利用した Character モデルが存在する。

app/models/character.rb
class Character < ApplicationRecord; end
app/models/female_character.rb
class FemaleCharacter < Character; end
app/models/male_character.rb
class MaleCharacter < Character; end

Character モデルは AnimeCharacter モデルを通じて Anime モデルと多対多のアソシエーションを持っている。

app/models/character.rb
class Character < ApplicationRecord
  has_many :anime_characters
end
app/models/anime_character.rb
class AnimeCharacter < ApplicationRecord
  belongs_to :anime
  belongs_to :character
end
app/models/anime.rb
class Anime < ApplicationRecord
  has_many :anime_characters
  has_many :characters, through: :anime_characters
end
anime = Anime.find_by(title: '偽物語')
anime.characters.pluck(:type, :name)
#=> [["MaleCharacter", "阿良々木 暦"], ["FemaleCharacter", "阿良々木 火憐"], ["FemaleCharacter", "阿良々木 月火"]]

ここで、Anime モデルの characters アソシエーションに条件を追加し、男性キャラクター (MaleCharacter) あるいは女性キャラクター (FemaleCharacter) のみに絞り込みたい。

方法

app/models/anime.rb
class Anime < ApplicationRecord
  has_many :anime_characters
  has_many :characters, through: :anime_characters
  has_many :male_characters, -> { where(type: MaleCharacter.to_s) },
           through: :anime_characters, source: :character
  has_many :female_characters, -> { where(type: FemaleCharacter.to_s) },
           through: :anime_characters, source: :character
end
anime = Anime.find_by(title: '偽物語')
anime.female_characters.pluck(:type, :name)
#=> [["FemaleCharacter", "阿良々木 火憐"], ["FemaleCharacter", "阿良々木 月火"]]
10
6
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
10
6