首页 > 解决方案 > 处理具有三种连接类型的 ActiveRecord where 子句的最佳方法

问题描述

查找具有与特定属性 ID 匹配的各种子对象的所有对象的最佳方法是什么?

采取以下模型:

顶级型号:

class InstagramPost < ApplicationRecord
  has_many :instagram_post_hashtags
  has_many :instagram_post_mentions
  has_many :instagram_post_locations
end

class InstagramHashtag < ApplicationRecord
  has_many :instagram_post_hashtags
  has_many :instagram_posts, through: :instagram_post_hashtags
end

class InstagramMention < ApplicationRecord
  has_many :instagram_post_mentions
  has_many :instagram_posts, through: :instagram_post_mentions
end

class InstagramLocation < ApplicationRecord
  has_many :instagram_post_locations
  has_many :instagram_posts, through: :instagram_post_locations
end

加入:

class InstagramPostHashtag < ApplicationRecord
  belongs_to :instagram_hashtag
  belongs_to :instagram_post
end

class InstagramPostLocation < ApplicationRecord
  belongs_to :instagram_location
  belongs_to :instagram_post
end

class InstagramPostMention < ApplicationRecord
  belongs_to :instagram_mention
  belongs_to :instagram_post
end

现在说我有三个 ID 数组:

instagram_hashtag_ids = [12,20,23]
instagram_location_ids = [4,12,30]
instagram_mention_ids = [121,21,31]

如果我想找到所有InstagramPost具有InstagramPostHashtag, InstagramPostLocation, 并且InstagramPostMention必须与上述所有数组 ID 匹配的内容;我在想我可以做类似的事情:

@instagram_posts = InstagramPost.joins(:instagram_post_hashtags).where("instagram_post_hashtags.instagram_hashtag_id IN (#{instagram_hashtag_ids})")

然后获取这些结果,并在下一个数组上进行搜索:

@instagram_posts = @instagram_posts.joins(:instagram_post_locations).where("instagram_post_locations.instagram_location_id IN (#{instagram_location_ids})")

等等...

这似乎是一种非常糟糕的方法,因为如果数组中没有 ID,它将返回空。事实上,即使所有数组中都有 ID 并且有数据可以反映这一点(可能是 PostgreSQL 的问题?),大多数时候它还是没有结果。

查询的最佳方法是InstagramPost什么?

标签: ruby-on-railspostgresqlactiverecord

解决方案


要获取所有InstagramPost具有与给定 id 数组匹配的连接表的 s:

@instagram_posts = InstagramPost.joins(
  :instagram_post_hashtags,
  :instagram_post_mentions,
  :instagram_post_locations
).where(
  instagram_post_hashtags: { instagram_hashtag_id: instagram_hashtag_ids },
  instagram_post_locations: { instagram_location_id: instagram_location_ids }, 
  instagram_post_mentions: { instagram_mention_id: instagram_mention_ids }
)

推荐阅读