将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