ActiveRecord .merge没有处理两种关系

时间:2015-09-02 22:00:59

标签: sql ruby-on-rails activerecord

我的应用中有以下型号:

class Company < ActiveRecord::Base
  has_many :gallery_cards, dependent: :destroy
  has_many :photos, through: :gallery_cards
  has_many :direct_photos, class_name: 'Photo'
end

class Photo < ActiveRecord::Base
  belongs_to :gallery_card
  belongs_to :company
end

class GalleryCard < ActiveRecord::Base
  belongs_to :company
  has_many :photos
end

如您所见,Company has_many :photos, through: :gallery_cards以及has_many :photosPhoto同时包含gallery_card_idcompany_id列。

我希望能够做的是写一个像@company.photos这样的查询,它返回所有公司照片的ActiveRecord :: Relation。在我的Company模型中,我目前使用下面的方法,但它返回一个数组或ActiveRecord对象,而不是关系。

def all_photos
   photos + direct_photos
end

我尝试过使用.merge()方法(见下文),但这会返回一个空关系。我认为原因是因为用于选择@company.photos@company.direct_photos的条件不同。 This SO post更详细地解释了它。

@company = Company.find(params[:id])
photos = @company.photos
direct_photos = @company.direct_photos
direct_photos.merge(photos) = []
photos.merge(direct_photos) = []

我还尝试了.joins.includes的多种组合,但没有成功。

这可能是原始SQL查询的候选者,但我的SQL技能相当基本。

为了它的价值,我重新审视了这个并提出了(帮助)另一个查询,一次抓取所有内容,而不是为第二个查询构建一个id数组。这还包括其他连接表:

Photo.joins("
   LEFT OUTER JOIN companies ON photos.company_id = #{id}
   LEFT OUTER JOIN gallery_cards ON gallery_cards.id = photos.gallery_card_id
   LEFT OUTER JOIN quote_cards ON quote_cards.id = photos.quote_card_id
   LEFT OUTER JOIN team_cards ON team_cards.id = photos.team_card_id
   LEFT OUTER JOIN who_cards ON who_cards.id = photos.who_card_id
   LEFT OUTER JOIN wild_cards ON wild_cards.id = photos.wild_card_id"
   ).where("photos.company_id = #{id}
       OR gallery_cards.company_id = #{id}
       OR quote_cards.company_id = #{id}
       OR team_cards.company_id = #{id}
       OR who_cards.company_id = #{id}
       OR wild_cards.company_id = #{id}").uniq

1 个答案:

答案 0 :(得分:1)

ActiveRecord的Dropzone.js返回交叉点而不是两个查询的并集 - 违反直觉的IMO。

要查找联合,您需要使用gallery_cards,而ActiveRecord的内置支持较差。因此,我认为您最好在SQL中编写条件:

photos

ETA 该查询将photosgallery_cardsmerge相关联,该LEFT OUTER JOIN会保留这些照片行而不会显示相关的图库卡行。然后,您可以根据company_id列或关联的def all_photos Photo.joins("LEFT OUTER JOIN gallery_cards ON gallery_cards.id = photos.gallery_card_id") .joins("LEFT OUTER JOIN quote_cards ON quote_cards.id = photos.quote_card_id") .where("photos.company_id = :id OR gallery_cards.company_id = :id OR quote_cards.company_id = :id", id: id) end 列进行查询 - 在这种情况下,来自任一表的virtualenv

您可以利用ActiveRecord范围链来加入和查询其他表:

{{1}}