将select和collect方法转换为连接

时间:2014-12-18 08:33:17

标签: mysql ruby-on-rails activerecord

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

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

如何使用联接代替收集和选择?

1 个答案:

答案 0 :(得分:0)

应该是(使用 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_bookingsbookings_users作为关联,因此,例如,在模型中它将导致:

has_and_belongs_to_many :users

has_and_belongs_to_many :bookings, table_name: :users_bookings