Ruby on rails 使用包含的或从句
基于以下内容,我想根据一位艺术家和他们的艺术家信用查询相册。artist_credit association是多态的,可以属于发行版或曲目。这阻止了我做HMT。我可以通过在我的查询中执行包含操作从曲目端抓取相册,如下所示:Ruby on rails 使用包含的或从句,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,基于以下内容,我想根据一位艺术家和他们的艺术家信用查询相册。artist_credit association是多态的,可以属于发行版或曲目。这阻止了我做HMT。我可以通过在我的查询中执行包含操作从曲目端抓取相册,如下所示: Album.includes(tracks: :artist_credits).where(artist_credits: { id: artist_id }) 但我想做的是同时掌握曲目和发行版。我曾想过使用or子句,但出现以下错误: ArgumentError (Rel
Album.includes(tracks: :artist_credits).where(artist_credits: { id: artist_id })
但我想做的是同时掌握曲目和发行版。我曾想过使用or子句,但出现以下错误:
ArgumentError (Relation passed to #or must be structurally compatible. Incompatible values: [:includes])
尝试此操作时:
Album.includes([tracks: :artist_credits, releases: :artist_credits]).where(artist_credits: { id: artist_id }).or(where(artist_credits: { id: artist_id }))
我怎样才能让它工作?有更好的方法吗
class Album < ApplicationRecord
has_many :releases, dependent: :destroy
has_many :tracks, dependent: :destroy
has_many :album_artists, dependent: :destroy
has_many :artists, through: :album_artists
end
class Track < ApplicationRecord
has_many :artist_credits, as: :creditable, dependent: :destroy
belongs_to :album
end
class Release < ApplicationRecord
has_many :artist_credits, as: :creditable, dependent: :destroy
belongs_to :album
end
class ArtistCredit < ApplicationRecord
belongs_to :artist
belongs_to :creditable, polymorphic: true # release or track
end
我建议如下
class Album < ApplicationRecord
scope :accredited_artist, ->(artist_id) {
includes([tracks: :artist_credits, releases: :artist_credits])
.where(id:
where(
id: Track.accredited_artist(artist_id).select(:album_id)
).or(
where(
id: Release.accredited_artist(artist_id).select(:album_id)
)
)
)
}
end
class Track < ApplicationRecord
scope :accredited_artist, ->(artist_id) {
joins(:artist_credits).where(artist_credits: { id: artist_id })
}
end
class Release < ApplicationRecord
scope :accredited_artist, ->(artist_id) {
joins(:artist_credits).where(artist_credits: { id: artist_id })
}
end
在这种情况下使用select会不会有点性能问题?@CarlEdwards不确定我是否理解这个问题。主要问题是您想使用includes和本机rails或condition。在where上下文中,我可能会混淆select。@ActiveRecord::Relation上的Carlewards select正在指定SQL语句中要选择的列。这与Arrayselect不同,Arrayselect是迭代的,需要一个块。这回答了你的问题吗?是的。谢谢你的澄清。
SELECT
albums.*
FROM
albums
WHERE
albums.id IN (
SELECT
albums.id
FROM
albums
WHERE
albums.id IN (
SELECT
tracks.album_id
FROM
tracks
INNER JOIN artist_credits ON [whatever your join is here]
WHERE
artist_credits.artist_id = [ID]) OR
albums.id IN (
SELECT
releases.album_id
FROM
releases
INNER JOIN artist_credits ON [whatever your join is here]
WHERE
artist_credits.artist_id = [ID])
)