试试下面的——它不是一个单一的查询,但我认为它比一个带有大连接表的单一查询要好:
public_addresses = Address.where(is_public: true)
# => get all public addresses
user_addresses = current_user.groups.includes(:group_members => :address).
# includes is to eager load records to avoid N+1 queries
flat_map{|g| g.group_members.map(&:address)}
# inner block returns array of addresses for each group
# flat_map converts the array of arrays to single level
# => get all addresses associated with the user
all_addresses = (public_addresses + user_addresses).uniq
# => remove duplicates
为了加快查询速度,为较慢的查询添加索引。例如
add_index :groups, :user_id
# this speeds up finding groups for a given user
add_index :group_members, :group_id
# this speeds up finding group_members for a given group
add_index :addresses, :group_member_id
# this speeds up finding addresses for a given group_member
其他选项是user_addresses
使用join
表格
user_addresses = Address.joins(group_member: group).where(groups: {user_id: current_user.id} )