将select和collect方法转换为连接

我正在学习加入我有三个模型

class Booking < ActiveRecord::Base has_and_belongs_to_many :groups has_and_belongs_to_many :users end class User < ActiveRecord::Base belongs_to :group has_and_belongs_to_many :bookings end class Group < ActiveRecord::Base has_many :users has_and_belongs_to_many :bookings end booking = Booking.first booking.groups.collect{|g| g.users.select{|u| !self.users.include? u}}.flatten 

我希望得到所有未在预订组中预订的用户

 booking=Booking.first booking.groups.collect{|g| g.users.select{|u| !self.users.include? u}}.flatten 

如何使用连接而不是收集和选择?

它应该是(使用arel gem):

 class User < ActiveRecord::Base scope :non_booked_for, ->(booking_id) { users = User.arel_table bookings = Booking.arel_table groups = Group.arel_table where(groups_bookings[:booking_id].eq(booking_id) .and(groups_bookings[:group_id].eq(users[:group_id]))) .not.where(user_bookings[:user_id].eq(users[:id]) .and(user_bookings[:booking_id].eq(booking_id))) end end 

用法:

 users = User.non_booked_for Booking.first.id 

它只对所有属于组和预订的用户使用否定,其组也属于该预订。 但是我不确定否定在这里会正常工作,所以应该调试它。 请在两个表名称中选择: users_bookings ,或者关联的bookings_users ,因此,例如,在模型中,它将导致:

 has_and_belongs_to_many :users has_and_belongs_to_many :bookings, table_name: :users_bookings