查找所有具有与某些属性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
必须与上述所有数组ID匹配的所有InstagramPostMention
;我以为我可以做类似的事情:
@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
的最佳方法是什么?
答案 0 :(得分:2)
要获取所有具有与给定ID数组匹配的联接表的InstagramPost
:
@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 }
)