Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the has_member and has_group association helpers to specify model class name #60

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Set up your member models:
```ruby
class User
include Mongoid::Document

groupify :group_member
groupify :named_group_member
end
Expand Down Expand Up @@ -131,10 +131,44 @@ Example:
class Organization < Group
has_members :offices, :equipment
end

class InternationalOrganization < Organization
has_member :offices, class_name: 'CustomOfficeClass'
has_member :equipment, class_name: 'CustomEquipmentClass'
end
```

Mongoid works the same way by creating Mongoid relations.

##### Group Associations on Member (ActiveRecord only)

Your member class can be configured to create associations for each expected group type.
For example, let's say that your member class will have multiple types of organizations as groups.
The following configuration adds `organizations` and `international_organizations` associations
on the member model:

```ruby
class Group < ActiveRecord::Base
groupify :group, members: [:users, :assignments], default_members: :users
end

class Organization < Group
has_members :offices, :equipment
end

class InternationalOrganization < Organization
end

class Member < ActiveRecord::Base
groupify :group_member

has_group :organizations, class_name: 'Organization'
has_group :international_organizations, class_name: 'InternationalOrganization'
end
```

Mongoid does not support the `has_group` helper method.

## Usage

### Create groups and add members
Expand Down
23 changes: 18 additions & 5 deletions lib/groupify/adapter/active_record/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,22 @@ def member_classes
# Define which classes are members of this group
def has_members(*names)
Array.wrap(names.flatten).each do |name|
has_member name
end
end

def has_member(name, options = {})
klass_name = options[:class_name]

if klass_name.nil?
klass = name.to_s.classify.constantize
register(klass)
association_name = name.is_a?(Symbol) ? name : klass.model_name.plural.to_sym
else
klass = klass_name.to_s.classify.constantize
association_name = name.to_sym
end

register(klass, association_name)
end

# Merge two groups. The members of the source become members of the destination, and the source is destroyed.
Expand All @@ -93,10 +106,10 @@ def merge!(source_group, destination_group)

protected

def register(member_klass)
def register(member_klass, association_name = nil)
(@member_klasses ||= Set.new) << member_klass

associate_member_class(member_klass)
associate_member_class(member_klass, association_name)

member_klass
end
Expand Down Expand Up @@ -135,8 +148,8 @@ def destroy(*args)
end
end

def associate_member_class(member_klass)
define_member_association(member_klass)
def associate_member_class(member_klass, association_name = nil)
define_member_association(member_klass, association_name)

if member_klass == default_member_class
define_member_association(member_klass, :members)
Expand Down
15 changes: 10 additions & 5 deletions lib/groupify/adapter/active_record/group_member.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ module GroupMember
class_name: Groupify.group_membership_class_name
end

has_many :groups, ->{ distinct },
through: :group_memberships_as_member,
as: :group,
source_type: @group_class_name,
extend: GroupAssociationExtensions
has_group :groups
end

module GroupAssociationExtensions
Expand Down Expand Up @@ -144,6 +140,15 @@ def in_other_groups(*groups)
def shares_any_group(other)
in_any_group(other.groups)
end

def has_group(name, options = {})
has_many name.to_sym, ->{ distinct }, {
through: :group_memberships_as_member,
source: :group,
source_type: @group_class_name,
extend: GroupAssociationExtensions
}.merge(options.slice :class_name)
end
end
end
end
Expand Down
23 changes: 19 additions & 4 deletions lib/groupify/adapter/mongoid/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,22 @@ def member_classes
# Define which classes are members of this group
def has_members(*names)
Array.wrap(names.flatten).each do |name|
has_member name
end
end

def has_member(name, options = {})
klass_name = options[:class_name]

if klass_name.nil?
klass = name.to_s.classify.constantize
register(klass)
association_name = name.is_a?(Symbol) ? name : klass.model_name.plural.to_sym
else
klass = klass_name.to_s.classify.constantize
association_name = name.to_sym
end

register(klass, association_name)
end

# Merge two groups. The members of the source become members of the destination, and the source is destroyed.
Expand Down Expand Up @@ -101,9 +114,11 @@ def merge!(source_group, destination_group)

protected

def register(member_klass)
def register(member_klass, association_name = nil)
(@member_klasses ||= Set.new) << member_klass
associate_member_class(member_klass)

associate_member_class(member_klass, association_name)

member_klass
end

Expand Down Expand Up @@ -137,7 +152,7 @@ def delete(*args)
end
end

def associate_member_class(member_klass)
def associate_member_class(member_klass, association_name = nil)
association_name ||= member_klass.model_name.plural.to_sym

has_many association_name, class_name: member_klass.to_s, dependent: :nullify, foreign_key: 'group_ids', extend: MemberAssociationExtensions
Expand Down