Rails - 过滤多对多
Rails - filter many to many
我在 'Event' 和 'Member' 之间有一个多对多的关系。我目前正在尝试过滤掉所有不属于某个成员的事件。
我可以做相反的事情,我可以 select 属于特定事件的所有事件。我是这样做的:
class Event < ApplicationRecord
has_and_belongs_to_many :members
scope :filter_by_member, -> (member) { joins(:members).where( members: { id: member.id } ) }
end
class Member < ApplicationRecord
has_and_belongs_to_many :events
end
我试图通过将 where
更改为 where.not
来获得相反的行为(所有不属于成员的事件);但是;这只是 select 事件 table.
中的所有记录
这是我试图在 rails 控制台中获取所有不属于成员的事件,在将 where
切换到 where.not
之后。然而,正确的输出应该是事件 2 和事件 3 在最后一行被 select 编辑(因为事件 1 属于 sample_member);所有 3 个都在 selected.
irb(main):001:0> sample_member = Member.find(2)
Member Load (0.3ms) SELECT "members".* FROM "members" WHERE "members"."id" = LIMIT [["id", 2], ["LIMIT", 1]]
=> #<Member id: 2, uid: nil, name: "John", created_at: "2021-10-23 14:30:38.434442000 -0500", updated_at: "2021-10-23 14:30:38.434442000 -0500", isAdmin: nil, email: nil>
irb(main):002:0> sample_member.events
Event Load (0.4ms) SELECT "events".* FROM "events" INNER JOIN "events_members" ON "events"."id" = "events_members"."event_id" WHERE "events_members"."member_id" = [["member_id", 2]]
=>
[#<Event:0x00007f02f0aeb4e8
id: 1,
date: nil,
description: "Please come",
isMandatory: nil,
location: nil,
admin_id: nil,
created_at: Sat, 23 Oct 2021 14:27:32.966994000 CDT -05:00,
updated_at: Sat, 23 Oct 2021 14:27:32.966994000 CDT -05:00,
time: nil,
datetime: nil,
name: "Fun event">]
irb(main):003:0> Event.filter_by_member sample_member
Event Load (0.3ms) SELECT "events".* FROM "events" INNER JOIN "events_members" ON "events_members"."event_id" = "events"."id" INNER JOIN "members" ON "members"."id" = "events_members"."member_id" WHERE "members"."id" != [["id", 2]]
=>
[#<Event:0x00005651319bf3d8
id: 1,
date: nil,
description: "Please come",
isMandatory: nil,
location: nil,
admin_id: nil,
created_at: Sat, 23 Oct 2021 14:27:32.966994000 CDT -05:00,
updated_at: Sat, 23 Oct 2021 14:27:32.966994000 CDT -05:00,
time: nil,
datetime: nil,
name: "Fun event">,
#<Event:0x00005651319bf270
id: 2,
date: nil,
description: "Important",
isMandatory: nil,
location: nil,
admin_id: nil,
created_at: Sat, 23 Oct 2021 14:29:39.380136000 CDT -05:00,
updated_at: Sat, 23 Oct 2021 14:29:39.380136000 CDT -05:00,
time: nil,
datetime: nil,
name: "Conference">,
#<Event:0x00005651319bf158
id: 3,
date: nil,
description: "this is orientation",
isMandatory: false,
location: "",
admin_id: nil,
created_at: Sat, 23 Oct 2021 14:39:13.186162000 CDT -05:00,
updated_at: Sat, 23 Oct 2021 14:39:13.186162000 CDT -05:00,
time: nil,
datetime: nil,
name: "orientation">]
有什么线索吗?
最简单的方法是使用 WHERE events.id NOT IN (...)
子查询:
Event.where.not(
id: member.events
)
我在 'Event' 和 'Member' 之间有一个多对多的关系。我目前正在尝试过滤掉所有不属于某个成员的事件。
我可以做相反的事情,我可以 select 属于特定事件的所有事件。我是这样做的:
class Event < ApplicationRecord
has_and_belongs_to_many :members
scope :filter_by_member, -> (member) { joins(:members).where( members: { id: member.id } ) }
end
class Member < ApplicationRecord
has_and_belongs_to_many :events
end
我试图通过将 where
更改为 where.not
来获得相反的行为(所有不属于成员的事件);但是;这只是 select 事件 table.
这是我试图在 rails 控制台中获取所有不属于成员的事件,在将 where
切换到 where.not
之后。然而,正确的输出应该是事件 2 和事件 3 在最后一行被 select 编辑(因为事件 1 属于 sample_member);所有 3 个都在 selected.
irb(main):001:0> sample_member = Member.find(2)
Member Load (0.3ms) SELECT "members".* FROM "members" WHERE "members"."id" = LIMIT [["id", 2], ["LIMIT", 1]]
=> #<Member id: 2, uid: nil, name: "John", created_at: "2021-10-23 14:30:38.434442000 -0500", updated_at: "2021-10-23 14:30:38.434442000 -0500", isAdmin: nil, email: nil>
irb(main):002:0> sample_member.events
Event Load (0.4ms) SELECT "events".* FROM "events" INNER JOIN "events_members" ON "events"."id" = "events_members"."event_id" WHERE "events_members"."member_id" = [["member_id", 2]]
=>
[#<Event:0x00007f02f0aeb4e8
id: 1,
date: nil,
description: "Please come",
isMandatory: nil,
location: nil,
admin_id: nil,
created_at: Sat, 23 Oct 2021 14:27:32.966994000 CDT -05:00,
updated_at: Sat, 23 Oct 2021 14:27:32.966994000 CDT -05:00,
time: nil,
datetime: nil,
name: "Fun event">]
irb(main):003:0> Event.filter_by_member sample_member
Event Load (0.3ms) SELECT "events".* FROM "events" INNER JOIN "events_members" ON "events_members"."event_id" = "events"."id" INNER JOIN "members" ON "members"."id" = "events_members"."member_id" WHERE "members"."id" != [["id", 2]]
=>
[#<Event:0x00005651319bf3d8
id: 1,
date: nil,
description: "Please come",
isMandatory: nil,
location: nil,
admin_id: nil,
created_at: Sat, 23 Oct 2021 14:27:32.966994000 CDT -05:00,
updated_at: Sat, 23 Oct 2021 14:27:32.966994000 CDT -05:00,
time: nil,
datetime: nil,
name: "Fun event">,
#<Event:0x00005651319bf270
id: 2,
date: nil,
description: "Important",
isMandatory: nil,
location: nil,
admin_id: nil,
created_at: Sat, 23 Oct 2021 14:29:39.380136000 CDT -05:00,
updated_at: Sat, 23 Oct 2021 14:29:39.380136000 CDT -05:00,
time: nil,
datetime: nil,
name: "Conference">,
#<Event:0x00005651319bf158
id: 3,
date: nil,
description: "this is orientation",
isMandatory: false,
location: "",
admin_id: nil,
created_at: Sat, 23 Oct 2021 14:39:13.186162000 CDT -05:00,
updated_at: Sat, 23 Oct 2021 14:39:13.186162000 CDT -05:00,
time: nil,
datetime: nil,
name: "orientation">]
有什么线索吗?
最简单的方法是使用 WHERE events.id NOT IN (...)
子查询:
Event.where.not(
id: member.events
)