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

Rails 7中如何筛选排除当前用户自有及已申请的项目列表

筛选用户未创建且未申请的项目列表

你的问题出在使用joins(:applicants)进行内连接,这会自动过滤掉没有任何申请者的项目,而且后续的where.not(applicants: {user_id: current_user.id})逻辑有误——只要项目存在其他申请者,即使你已经申请过,这个项目也会被错误地保留下来。

下面是几种正确的实现方式:

方法1:子查询排除已申请项目ID(直观易读)

先获取当前用户已申请的所有项目ID,再从候选列表中排除这些ID:

# 获取当前用户已申请的项目ID集合
applied_project_ids = current_user.applicants.pluck(:project_id)

# 筛选条件:不是自己创建的 + 未申请过的项目
@sugested_projects = Project.where.not(user_id: current_user.id)
                            .where.not(id: applied_project_ids)

这个方法逻辑清晰,适合数据量不大的场景,不需要复杂的SQL语法。

方法2:使用左外连接(Left Join)+ 去重

通过left_joins保留所有非用户创建的项目,再筛选出「无申请者」或「申请者不是当前用户」的项目,最后去重避免重复结果:

@sugested_projects = Project.where.not(user_id: current_user.id)
                            .left_joins(:applicants)
                            .where("applicants.user_id != ? OR applicants.id IS NULL", current_user.id)
                            .distinct

left_joins会返回所有符合条件的Project,即使没有对应的Applicant记录;distinct用于消除同一项目因多个申请者产生的重复行。

方法3:NOT EXISTS子查询(高效适合大数据量)

直接在数据库层面用子查询判断当前用户是否申请过该项目,避免加载大量ID到内存,性能更优:

@sugested_projects = Project.where.not(user_id: current_user.id)
                            .where.not(
                              id: Applicant.select(:project_id).where(user_id: current_user.id)
                            )

等价于SQL中的NOT EXISTS逻辑,数据库会高效处理这种关联查询,适合项目和申请者数据较多的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:27:11