Rails多外键关联问题:FeedPost如何获取所有关联航班的Location?
嘿,这个场景我太熟悉了!Rails原生确实没有直接通过单个has_many关联同时拉取两个不同关联对象的方式(你之前的写法会因为重复定义同名关联导致后者覆盖前者,所以只返回目的地),不过我们可以用几种优雅的原生方式实现需求:
方法1:自定义实例方法(高效单次查询版)
直接在FeedPost模型里写一个实例方法,用SQL子查询一次性获取所有关联的出发地和目的地:
class FeedPost < ApplicationRecord has_many :flights def locations Location.where( id: Flight.select("origin_id UNION SELECT destination_id").where(feed_post_id: id) ) end end
这里用UNION合并航班表中origin_id和destination_id的所有唯一ID,再关联查询对应的Location记录,全程只有一次数据库查询,效率很高。调用FeedPost.first.locations就能拿到所有符合要求的地点了。
方法2:拆分关联后合并(支持链式调用)
先分别定义出发地和目的地的独立关联,再通过or方法合并两个关联关系并去重:
class FeedPost < ApplicationRecord has_many :flights has_many :origin_locations, through: :flights, source: :origin has_many :destination_locations, through: :flights, source: :destination def locations origin_locations.or(destination_locations).distinct end end
这种方式的优势是返回的是ActiveRecord::Relation对象,你可以继续链式调用其他查询方法(比如.where(country: "CN")、.order(name: :asc)),灵活性更强。
为什么你原来的写法不生效?
Rails中重复定义同名的has_many关联时,后面的定义会完全覆盖前面的,所以你最后只有destination的关联被保留,自然只能拿到目的地。
内容的提问来源于stack exchange,提问作者Arel
相关产品推荐
相关产品推荐

