我有一个Adventure
模型,它是Destination
和User
之间的联接表(还有其他属性,例如zipcode
和time_limit
)。我想创建一个query
,它会返回Destinations
Adventure
之间的Destination
User
与Adventure
当前正在尝试创建User
的{{1}} }} 不存在。
当Adventure
点击以启动新的Adventure
时,应用的工作方式会创建user_id
,User
为id
&# 39; s Destination
然后运行一种方法来提供随机Adventure.create(user_id: current_user.id)
,例如:
current_user.adventures.new
(它实际上在做SQL queries
)但同样的事情
我尝试过将原始.joins
编写为使用Destination.joins(:adventures).where.not('adventures.user_id != ?'), user.id)
的一些内容。以下是一些例子:
Destination.joins('LEFT OUTER JOIN adventure ON destination.id = adventure.destination_id').where('adventure.user_id != ?', user.id)
{{1}}
答案 0 :(得分:6)
以下内容应返回用户在任何冒险中尚未访问过的所有目的地:
destinations = Destination.where('id NOT IN (SELECT destination_id FROM adventures WHERE user_id = ?)', user.id)
要选择随机的一个,请附加以下内容之一:
.all.sample
# or
.pluck(:id).sample
取决于您是想要完整记录还是只是id。
答案 1 :(得分:2)
不需要加入,这应该做:
Destination.where(['id not in ?', user.adventures.pluck(:destination_id)])
答案 2 :(得分:1)
在您的第一次尝试中,我看到使用where.not
的等于运算符时遇到的问题。在你的第一次尝试中:
Destination.joins(:adventures).where.not('adventures.user_id != ?'), user.id)
你正在做where.not('adventures.user_id != ?'), user.id)
。我明白这恰恰与你想要的相反,不是吗?您是否应该将其称为where.not('adventures.user_id = ?', user.id)
,即等于=
?
我认为以下查询适用于该要求:
Destination.joins(:adventures).where.not(adventures: { user_id: user.id })
我在第二种方法中看到的唯一问题是在destinations
和adventures
条件下使用join
和where
表格。表名应为复数。查询应该是:
Destination
.joins('LEFT OUTER JOIN adventures on destinations.id = adventures.destination_id')
.where('adventures.user_id != ?', user.id)
答案 3 :(得分:0)
ActiveRecord不会执行加入条件,但您可以使用用户destinations
关系(例如has_many :destinations, through: adventures
)作为子选择,从而产生WHERE NOT IN (SELECT...)
查询表达非常简单,不需要使用sql字符串shenanigans,多个查询或撤回临时的id组:
Destination.where.not(id: user.destinations)
如果您愿意,您还可以将上述条款与附加条款,排序和分组条款相关联。
答案 4 :(得分:0)
我使用this answer和this other answer混合解决了这个问题,并提出:
destination = Destination.where
.not(id: Adventure.where(user: user)
.pluck(:destination_id)
)
.sample
.not(id: Adventure.where(user: user).pluck(:destination_id))
部分排除了之前用户冒险中出现的目的地。
.sample
部分将从结果中选择一个随机目的地。