问题
I am learning joins I have three models
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
I want to get all users which are not booked in booking groups some thing like this
booking=Booking.first
booking.groups.collect{|g| g.users.select{|u| !self.users.include? u}}.flatten
How can I do it with joins instead collect and select?
回答1:
It should be something like (using 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
usage:
users = User.non_booked_for Booking.first.id
It just uses negation to all users, which belong to group and bookings, and its group belongs to that booking too. But I'm not sure that the negation will work properly here, so it should be debugged. And please select on of the two table names: users_bookings, or bookings_users for the associations, so, for example, in models it will lead to:
has_and_belongs_to_many :users
has_and_belongs_to_many :bookings, table_name: :users_bookings
来源:https://stackoverflow.com/questions/27542188/convert-select-and-collect-methods-into-joins