Rails ActiveRecord:关联查询后将集合类型从Book改为Author
嘿,这个问题我之前也碰到过,咱们来调整下查询逻辑,直接拿到符合条件的Author对象,而不是Book。
推荐方案:单查询直接返回Author(更高效)
直接从Author模型入手,通过嵌套关联链关联到Book和Publisher,这样查询结果就是Author实例,同时用distinct避免同一个作者因为有多本符合条件的书被重复返回:
def get_old_authors_at_publisher(publisher, date) Author.joins(books: :publisher) .where(publishers: { id: publisher.id }) .where('books.publication_date < ?', date) .distinct end
这里joins(books: :publisher)相当于把Author→Book→Publisher的关联链打通,然后通过where限定目标出版社和出版日期,最后distinct让数据库层面去重,避免返回重复的Author对象。
备选方案:基于现有查询修改
如果你想保留原查询的结构,也可以分两步走:先提取符合条件的作者ID,再查询对应的Author:
def get_old_authors_at_publisher(publisher, date) # 提取所有符合条件的作者ID(去重) author_ids = publisher.books .joins(:author) .where('books.publication_date < ?', date) .pluck(:author_id) .uniq # 通过ID获取Author对象集合 Author.where(id: author_ids) end
原查询的问题所在
你原来的查询是从publisher.books开始的,这意味着整个查询的主模型是Book——哪怕你关联了Author,最终返回的还是满足筛选条件的Book实例,而不是关联的Author。所以要么换主模型发起查询,要么提取关联ID后再查Author,就能得到你想要的结果啦。
内容的提问来源于stack exchange,提问作者Quentin
相关产品推荐
相关产品推荐

