ruby-on-rails – 活动记录范围链接,如果已经加入,则忽略连接
我已经建模,用户在活动中出席了会议.
class User has_many :attendances has_many :events,through: :attendances class Event has_many :attendances scope :is_attending,-> { joins(:attendances).where(attendances:{attend_status: Attendance.attend_statuses[:attending] })} class Attendance belongs_to :event belongs_to :user enum attend_status: { attending: 0,not_attending: 1} 我的问题是关于范围查询和最佳实践. 我把大部分的范围查询都放在了Event上. 我想获取att_status = 0的特定用户的所有事件 user = User.find(...) user.events.is_attending 逻辑上我会想,这是最好的,最有意义 不过这会给我一个双重的内在联系 SELECT "events".* FROM "events" INNER JOIN "attendances" "attendances_events" ON "attendances_events"."event_id" = "events"."id" INNER JOIN "attendances" ON "events"."id" = "attendances"."event_id" WHERE "attendances"."user_id" = $1 AND "attendances"."attend_status" = 0 显然这会创造出不是我想要的重复项. 所以选择我知道我可以做 1)使用合并 Event scope :for_user,-> (user){ joins(:attendances).where(attendances: {user: user})} 然后打电话 Event.for_user(user).merge(Event.is_attending) 这给了我sql SELECT "events".* FROM "events" INNER JOIN "attendances" ON "attendances"."event_id" = "events"."id" WHERE "attendances"."user_id" = 59 AND "attendances"."attend_status" = 0 这就是我想要的 2)使用包括 如果我使用include而不是join,我不会得到重复加入.由于它分开加载事件,并且足够聪明,无法重复. Event scope :is_attending,-> { includes(:attendances).where(attendances: {attend_status: Attendance.attend_statuses[:attending] })} 但是我不想加载. 3)ASSUME表已经加入到范围之外 最后我可以假设表已经加入了调用范围之外, Event scope :is_attending,-> { where(attendances: {attend_status: Attendance.attend_statuses[:attending] })} 但这似乎对我来说有点愚蠢的设计,使得这个命名范围不太可用. 所以我的问题 1)最好的方法是什么? 2)有没有办法告诉活动记录忽略连接,如果他们已经发生了? 解决方法
我会使用接近你的第一个建议的东西,除了我将范围直接合并到你的内部模型(Attendance)上.
所以而不是: Event.for_user(用户).merge(Event.is_attending) 我会去: Event.for_user(用户).merge(Attendance.is_attending) 这是一个清晰的语法.您的is_attending范围不需要连接,每个类都负责了解如何过滤自身. 如果经常使用它,您可以创建一个for_attending_user(用户)范围来隐藏合并: class Event scope :for_attending_user,-> user { for_user(user).merge(Attendance.is_attending) } ... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |