You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7:演员自关联多对多模型查询报错排查

解决Actor关联报错并实现合作演员及影片查询功能

一、修复关联报错

报错根源是Actor模型中的has_many :actor_partners默认会在actor_partners表中查找actor_id字段,但你的表中只有actor1_id和actor2_id。需要拆分关联并明确指定外键:

修改actor.rb中的关联部分:

class Actor < ApplicationRecord
  # ... 其他关联和代码
  # 作为actor1的合作关系
  has_many :actor_partners_as_actor1, class_name: 'ActorPartner', foreign_key: 'actor1_id', dependent: :destroy
  # 作为actor2的合作关系
  has_many :actor_partners_as_actor2, class_name: 'ActorPartner', foreign_key: 'actor2_id', dependent: :destroy

  # 获取作为actor1时的合作演员(actor2)
  has_many :partners_as_actor1, through: :actor_partners_as_actor1, source: :actor2
  # 获取作为actor2时的合作演员(actor1)
  has_many :partners_as_actor2, through: :actor_partners_as_actor2, source: :actor1
end

这样就解决了Unknown column 'actor_partners.actor_id'的报错,因为关联现在明确绑定了actor1_id和actor2_id字段。

二、获取所有合作演员

如果只需要获取某演员的所有合作演员,在Actor模型中添加合并方法去重:

def all_partners
  partners_as_actor1.or(partners_as_actor2).distinct
end

调用示例:

actor = Actor.find(3)
actor.all_partners # 返回该演员所有合作过的演员集合

三、查询合作演员及对应影片

要同时获取合作演员和对应的影片信息,添加以下方法:

def partner_with_movies
  ActorPartner.where("actor1_id = ? OR actor2_id = ?", id, id)
              .joins(:actor1, :actor2, :movie)
              .select("
                CASE WHEN actor1_id = #{id} THEN actor2_id ELSE actor1_id END AS partner_id,
                CASE WHEN actor1_id = #{id} THEN actor2.name ELSE actor1.name END AS partner_name,
                movies.title AS movie_title,
                movies.id AS movie_id,
                actor_partners.movie_type
              ")
              .group_by { |item| [item.partner_id, item.partner_name] }
end

调用示例:

actor = Actor.find(3)
result = actor.partner_with_movies
# 遍历输出合作演员及对应影片
result.each do |(partner_id, partner_name), movies|
  puts "#{partner_name} 合作影片:"
  movies.each do |movie|
    puts "- 《#{movie.movie_title}》(类型:#{movie.movie_type})"
  end
end

四、优化建议

  • 可以将partner_with_movies的查询逻辑封装成scope,或创建数据库视图简化查询,减少重复代码。
  • 可以约定actor1_id < actor2_id来存储合作记录,避免重复数据,进一步简化查询逻辑。

内容的提问来源于stack exchange,提问作者tkhobbes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:53:22