私は、ユーザーが視聴している番組や視聴している番組を選択できるRailsアプリケーションを持っています。 ActiveRecordの団体は、多少のようになります。アクティブレコード:同じ親に属する異なるアソシエーションを照会します
class User
has_many :episodes_joins, :dependent => :delete_all, class_name: 'UsersEpisodesJoin'
has_many :episodes, through: :episodes_joins
has_many :shows_joins, :dependent => :delete_all, class_name: 'UsersShowsJoin'
has_many :shows, through: :shows_joins
end
class Show
has_many :episodes, dependent: :destroy
has_many :users_shows_joins, :dependent => :delete_all
has_many :users, through: :users_shows_joins
end
class Episode
belongs_to :show
has_many :users_episodes_joins, :dependent => :delete_all
has_many :users, through: :users_episodes_joins
end
class UsersShowsJoin
belongs_to :user
belongs_to :show
end
class UsersEpisodesJoin
belongs_to :user
belongs_to :episode
end
私は、ユーザーがそれぞれのために「特別なエピソードを」フィルタリングする許可したい(?「特別なエピソードは」trueに設定さepisode.specialを持っている)、個別に表示されます。このため、私はfilter_specials
という名前のUsersShowsJoinsテーブルにブール値の列を追加することを考えていました。私は今、このような何かをしたい:
episodes = user.episodes.where(special: false).to_a
user.episodes.where(special: true) do |epi|
show_join = UsersShowsJoins.where(user_id: user.id, show_id: epi.show.id).first
episodes << epi if show_join.nil? || !show_join.filter_specials?
end
# do something with 'episodes',
# which contains all non-special episodes,
# as well as special episodes of shows for which the user is not filtering these
可能性も、私はこれはDBクエリのトンを行います非常にハックと遅い実装である知っている、と私はそれを行うにはもっと良い方法があります確信しています1つのクエリで
さらに、ユーザーが選択したすべての番組をDBに照会して、同じユーザーのUsersEpisodesJoins行を持つ対応するエピソードをあらかじめロードしたいと考えています。何かのように:私は複雑なクエリのためのN + 1の問題が発生しないように
shows = user.shows.all
h = {}
shows.each do |show|
episodes = user.episodes.where(show_id: show.id).all
h[show] = episodes
end
# do something with h,
# which contains a user's watched episodes for each selected show
にはどうすれば、効率的にこれらのクエリを書くことができますか?
ありがとうございました!まさに私が必要としていたことですが、私はARのガイドを読んでいましたが、そのような詳細なJoining Tablesセクションがあることに気がつかなかったので、指摘していただきありがとうございます。 – rpinheiro