lib/groupify/adapter/active_record/named_group_collection.rb
module Groupify
module ActiveRecord
class NamedGroupCollection < Set
def initialize(member)
@member = member
@named_group_memberships = member.group_memberships_as_member.named
@group_names = @named_group_memberships.pluck(:group_name).map(&:to_sym)
super(@group_names)
end
def add(named_group, opts={})
named_group = named_group.to_sym
membership_type = opts[:as]
if @member.new_record?
@member.group_memberships_as_member.build(group_name: named_group, membership_type: nil)
else
@member.transaction do
@member.group_memberships_as_member.where(group_name: named_group, membership_type: nil).first_or_create!
end
end
if membership_type
if @member.new_record?
@member.group_memberships_as_member.build(group_name: named_group, membership_type: membership_type)
else
@member.group_memberships_as_member.where(group_name: named_group, membership_type: membership_type).first_or_create!
end
end
super(named_group)
end
alias_method :push, :add
alias_method :<<, :add
def merge(*args)
opts = args.extract_options!
named_groups = args.flatten
named_groups.each do |named_group|
add(named_group, opts)
end
end
alias_method :concat, :merge
def include?(named_group, opts={})
named_group = named_group.to_sym
if opts[:as]
as(opts[:as]).include?(named_group)
else
super(named_group)
end
end
def delete(*args)
opts = args.extract_options!
named_groups = args.flatten.compact
remove(named_groups, :delete_all, opts)
end
def destroy(*args)
opts = args.extract_options!
named_groups = args.flatten.compact
remove(named_groups, :destroy_all, opts)
end
def clear
@named_group_memberships.delete_all
super
end
alias_method :delete_all, :clear
alias_method :destroy_all, :clear
# Criteria to filter by membership type
def as(membership_type)
@named_group_memberships.as(membership_type).pluck(:group_name).map(&:to_sym)
end
protected
def remove(named_groups, method, opts)
if named_groups.present?
scope = @named_group_memberships.where(group_name: named_groups)
if opts[:as]
scope = scope.where(membership_type: opts[:as])
end
scope.send(method)
unless opts[:as]
named_groups.each do |named_group|
@hash.delete(named_group)
end
end
end
end
end
end
end