adhocracy 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/README.rdoc +1 -1
- data/app/models/adhocracy/membership.rb +15 -0
- data/app/models/adhocracy/membership_invitation.rb +31 -0
- data/app/models/adhocracy/membership_request.rb +31 -0
- data/config/locales/en.yml +14 -0
- data/db/migrate/20140306214416_create_adhocracy_memberships.rb +19 -0
- data/db/migrate/20140306214532_create_adhocracy_membership_requests.rb +23 -0
- data/db/migrate/20140306214552_create_adhocracy_membership_invitations.rb +23 -0
- data/lib/adhocracy/acceptable.rb +18 -0
- data/lib/adhocracy/acts_as_group.rb +65 -0
- data/lib/adhocracy/acts_as_member.rb +63 -0
- data/lib/adhocracy/membership_association.rb +49 -0
- data/lib/adhocracy/version.rb +1 -1
- data/lib/adhocracy.rb +4 -0
- data/spec/dummy/app/models/adhoc.rb +3 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/db/migrate/20140306214611_create_users.rb +6 -0
- data/spec/dummy/db/migrate/20140306214620_create_adhocs.rb +6 -0
- data/spec/dummy/db/schema.rb +67 -0
- data/spec/factories/adhoc.rb +4 -0
- data/spec/factories/adhocracy_membership_invitations.rb +8 -0
- data/spec/factories/adhocracy_membership_requests.rb +8 -0
- data/spec/factories/adhocracy_memberships.rb +7 -0
- data/spec/factories/users.rb +4 -0
- data/spec/lib/adhocracy/acts_as_group_spec.rb +179 -0
- data/spec/lib/adhocracy/acts_as_member_spec.rb +179 -0
- data/spec/models/adhocracy/membership_invitation_spec.rb +84 -0
- data/spec/models/adhocracy/membership_request_spec.rb +84 -0
- data/spec/models/adhocracy/membership_spec.rb +21 -0
- metadata +114 -75
- data/spec/dummy/log/test.log +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Mzc4MGI0NWEzMTM5YTA5Mzg4NDcyNjlkMTRhODdlN2E3OGVlMDFjOA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MWU2NTA1NTkyYTBiNGFjMDI3OTllN2U2ZTM4MjJmMjI4Yjc2MjJkMQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Y2U1ZDBiYjQ0NzZjNGNkMmFmOTFlOTYwMjVmN2U3NDEzNTI1MDA0ODU2ZDhl
|
10
|
+
YzFkZmJmM2JhNGJhODZiODQ2YzRkMzBlYzY3MTMxNDRmMmY4MTNkOWNjOTU1
|
11
|
+
YzQ2NWQxYTA1YjUyYWJiMjExMzg1NWE5NWMxYjU4MmVlNjg2ZGQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YTMyZTIwZjM2MjA5OWQxNzgyYWZlNTI1M2UzNmVkOTk1ZGMyZGM2ZTU3YzJm
|
14
|
+
ZDE4NWIyYmMzMWYwYjAyMDFmMGM0NGEyNDg5YmI3ZDQ3OGY2ZDMxM2E5YWE5
|
15
|
+
MjVmZDUxOTIzZWZhZmU2MWRmNGRlYzRjM2U0MTI4NmIxYmY2YWU=
|
data/README.rdoc
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
= Adhocracy {<img src="https://codeclimate.com/github/timothycommoner/adhocracy.png" />}[https://codeclimate.com/github/timothycommoner/adhocracy]
|
1
|
+
= Adhocracy {<img src="https://badge.fury.io/rb/adhocracy.png" alt="Gem Version" />}[http://badge.fury.io/rb/adhocracy] {<img src="https://travis-ci.org/timothycommoner/adhocracy.png?branch=master" alt="Build Status" />}[https://travis-ci.org/timothycommoner/adhocracy] {<img src="https://codeclimate.com/github/timothycommoner/adhocracy.png" />}[https://codeclimate.com/github/timothycommoner/adhocracy]
|
2
2
|
|
3
3
|
A group management engine for Rails.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Adhocracy
|
2
|
+
class Membership < ActiveRecord::Base
|
3
|
+
belongs_to :member, polymorphic: true
|
4
|
+
belongs_to :group, polymorphic: true
|
5
|
+
|
6
|
+
validate :membership_is_unique
|
7
|
+
|
8
|
+
private
|
9
|
+
def membership_is_unique
|
10
|
+
if self.member.member_of?(self.group)
|
11
|
+
errors[:base] << I18n.t("activerecord.errors.models.membership.not_unique")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Adhocracy
|
2
|
+
class MembershipInvitation < ActiveRecord::Base
|
3
|
+
include Acceptable
|
4
|
+
|
5
|
+
belongs_to :member, polymorphic: true
|
6
|
+
belongs_to :group, polymorphic: true
|
7
|
+
|
8
|
+
validate :no_pending_invitations, on: :create
|
9
|
+
validate :no_declined_invitations, on: :create
|
10
|
+
validate :not_currently_a_member, on: :create
|
11
|
+
|
12
|
+
private
|
13
|
+
def no_pending_invitations
|
14
|
+
if self.member.invited_to?(self.group, { pending: true })
|
15
|
+
errors[:base] << I18n.t("activerecord.errors.models.membership_invitation.still_pending")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def no_declined_invitations
|
20
|
+
if self.member.invited_to?(self.group, { declined: true })
|
21
|
+
errors[:base] << I18n.t("activerecord.errors.models.membership_invitation.already_declined")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def not_currently_a_member
|
26
|
+
if self.member.member_of?(self.group)
|
27
|
+
errors[:base] << I18n.t("activerecord.errors.models.membership_invitation.already_a_member")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Adhocracy
|
2
|
+
class MembershipRequest < ActiveRecord::Base
|
3
|
+
include Acceptable
|
4
|
+
|
5
|
+
belongs_to :member, polymorphic: true
|
6
|
+
belongs_to :group, polymorphic: true
|
7
|
+
|
8
|
+
validate :no_pending_requests, on: :create
|
9
|
+
validate :no_declined_requests, on: :create
|
10
|
+
validate :not_currently_a_member, on: :create
|
11
|
+
|
12
|
+
private
|
13
|
+
def no_pending_requests
|
14
|
+
if self.member.requested_membership_in?(self.group, { pending: true })
|
15
|
+
errors[:base] << I18n.t("activerecord.errors.models.membership_request.still_pending")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def no_declined_requests
|
20
|
+
if self.member.requested_membership_in?(self.group, { declined: true })
|
21
|
+
errors[:base] << I18n.t("activerecord.errors.models.membership_request.already_declined")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def not_currently_a_member
|
26
|
+
if self.member.member_of?(self.group)
|
27
|
+
errors[:base] << I18n.t("activerecord.errors.models.membership_request.already_a_member")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
en:
|
2
|
+
activerecord:
|
3
|
+
errors:
|
4
|
+
models:
|
5
|
+
membership:
|
6
|
+
not_unique: "Membership already exists."
|
7
|
+
membership_invitation:
|
8
|
+
still_pending: "Invitation still pending."
|
9
|
+
already_declined: "Cannot invite member again."
|
10
|
+
already_a_member: "Already a member."
|
11
|
+
membership_request:
|
12
|
+
still_pending: "Request still pending."
|
13
|
+
already_declined: "Cannot request membership again."
|
14
|
+
already_a_member: "Already a member."
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateAdhocracyMemberships < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :adhocracy_memberships do |t|
|
4
|
+
t.string :member_type
|
5
|
+
t.integer :member_id
|
6
|
+
t.string :group_type
|
7
|
+
t.integer :group_id
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :adhocracy_memberships,
|
13
|
+
[:member_id, :member_type],
|
14
|
+
name: "adhocracy_memberships_on_member"
|
15
|
+
add_index :adhocracy_memberships,
|
16
|
+
[:group_id, :group_type],
|
17
|
+
name: "adhocracy_memberships_on_group"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class CreateAdhocracyMembershipRequests < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :adhocracy_membership_requests do |t|
|
4
|
+
t.string :member_type
|
5
|
+
t.integer :member_id
|
6
|
+
t.string :group_type
|
7
|
+
t.integer :group_id
|
8
|
+
|
9
|
+
t.boolean :pending, null: false, default: true
|
10
|
+
t.boolean :accepted, null: false, default: false
|
11
|
+
t.boolean :declined, null: false, default: false
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :adhocracy_membership_requests,
|
17
|
+
[:member_id, :member_type],
|
18
|
+
name: "adhocracy_membership_requests_on_member"
|
19
|
+
add_index :adhocracy_memberships,
|
20
|
+
[:group_id, :group_type],
|
21
|
+
name: "adhocracy_membership_requests_on_group"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class CreateAdhocracyMembershipInvitations < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :adhocracy_membership_invitations do |t|
|
4
|
+
t.string :member_type
|
5
|
+
t.integer :member_id
|
6
|
+
t.string :group_type
|
7
|
+
t.integer :group_id
|
8
|
+
|
9
|
+
t.boolean :pending, null: false, default: true
|
10
|
+
t.boolean :accepted, null: false, default: false
|
11
|
+
t.boolean :declined, null: false, default: false
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :adhocracy_membership_invitations,
|
17
|
+
[:member_id, :member_type],
|
18
|
+
name: "adhocracy_membership_invitations_on_member"
|
19
|
+
add_index :adhocracy_memberships,
|
20
|
+
[:group_id, :group_type],
|
21
|
+
name: "adhocracy_membership_invitations_on_group"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Adhocracy
|
2
|
+
module Acceptable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def accept
|
6
|
+
if pending?
|
7
|
+
member.join_group(group)
|
8
|
+
update_attributes(pending: false, accepted: true, declined: false)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def decline
|
13
|
+
if pending?
|
14
|
+
update_attributes(pending: false, accepted: false, declined: true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Adhocracy
|
2
|
+
module ActsAsGroup
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def acts_as_group(options = {})
|
7
|
+
|
8
|
+
has_many :memberships, as: :group, class_name: "Adhocracy::Membership"
|
9
|
+
has_many :membership_invitations, as: :group,
|
10
|
+
class_name: "Adhocracy::MembershipInvitation"
|
11
|
+
has_many :membership_requests, as: :group,
|
12
|
+
class_name: "Adhocracy::MembershipRequest"
|
13
|
+
|
14
|
+
send :include, InstanceMethods
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
def members
|
20
|
+
MembershipAssociation.new(group: self).list_members_for_membership
|
21
|
+
end
|
22
|
+
|
23
|
+
def invited_members
|
24
|
+
MembershipAssociation.new(group: self).
|
25
|
+
list_members_for_membership_invitation
|
26
|
+
end
|
27
|
+
|
28
|
+
def membership_requests
|
29
|
+
MembershipAssociation.new(group: self).
|
30
|
+
list_members_for_membership_request
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_member(member)
|
34
|
+
MembershipAssociation.new(member: member, group: self).
|
35
|
+
create_membership
|
36
|
+
end
|
37
|
+
|
38
|
+
def invite_member(member)
|
39
|
+
MembershipAssociation.new(member: member, group: self).
|
40
|
+
create_membership_invitation
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_member(member)
|
44
|
+
MembershipAssociation.new(member: member, group: self).
|
45
|
+
destroy_membership
|
46
|
+
end
|
47
|
+
|
48
|
+
def has_member?(member)
|
49
|
+
MembershipAssociation.new(member: member, group: self).verify_membership
|
50
|
+
end
|
51
|
+
|
52
|
+
def invited?(member, params = {})
|
53
|
+
params.merge!({ member: member, group: self })
|
54
|
+
MembershipAssociation.new(params).verify_membership_invitation
|
55
|
+
end
|
56
|
+
|
57
|
+
def recieved_request_from?(member, params = {})
|
58
|
+
params.merge!({ member: member, group: self })
|
59
|
+
MembershipAssociation.new(params).verify_membership_request
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
ActiveRecord::Base.send :include, Adhocracy::ActsAsGroup
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Adhocracy
|
2
|
+
module ActsAsMember
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def acts_as_member(options = {})
|
7
|
+
|
8
|
+
has_many :memberships, as: :member, class_name: "Adhocracy::Membership"
|
9
|
+
has_many :membership_invitations, as: :member,
|
10
|
+
class_name: "Adhocracy::MembershipInvitation"
|
11
|
+
has_many :membership_requests, as: :member,
|
12
|
+
class_name: "Adhocracy::MembershipRequest"
|
13
|
+
|
14
|
+
send :include, InstanceMethods
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
def groups
|
20
|
+
MembershipAssociation.new(member: self).list_groups_for_membership
|
21
|
+
end
|
22
|
+
|
23
|
+
def group_invitations
|
24
|
+
MembershipAssociation.new(member: self).
|
25
|
+
list_groups_for_membership_invitation
|
26
|
+
end
|
27
|
+
|
28
|
+
def membership_requests
|
29
|
+
MembershipAssociation.new(member: self).
|
30
|
+
list_groups_for_membership_request
|
31
|
+
end
|
32
|
+
|
33
|
+
def join_group(group)
|
34
|
+
MembershipAssociation.new(member: self, group: group).create_membership
|
35
|
+
end
|
36
|
+
|
37
|
+
def request_membership_in(group)
|
38
|
+
MembershipAssociation.new(member: self, group: group).
|
39
|
+
create_membership_request
|
40
|
+
end
|
41
|
+
|
42
|
+
def leave_group(group)
|
43
|
+
MembershipAssociation.new(member: self, group: group).destroy_membership
|
44
|
+
end
|
45
|
+
|
46
|
+
def member_of?(group)
|
47
|
+
MembershipAssociation.new(member: self, group: group).verify_membership
|
48
|
+
end
|
49
|
+
|
50
|
+
def invited_to?(group, params = {})
|
51
|
+
params.merge!({ member: self, group: group })
|
52
|
+
MembershipAssociation.new(params).verify_membership_invitation
|
53
|
+
end
|
54
|
+
|
55
|
+
def requested_membership_in?(group, params = {})
|
56
|
+
params.merge!({ member: self, group: group })
|
57
|
+
MembershipAssociation.new(params).verify_membership_request
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
ActiveRecord::Base.send :include, Adhocracy::ActsAsMember
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Adhocracy
|
2
|
+
class MembershipAssociation
|
3
|
+
|
4
|
+
attr_accessor :params
|
5
|
+
def initialize(params)
|
6
|
+
@params = params
|
7
|
+
end
|
8
|
+
|
9
|
+
# Creates Methods:
|
10
|
+
# list_membership, create_membership, destroy_membership, verify_membership
|
11
|
+
# list_membership_request, create_membership_request,
|
12
|
+
# destroy_membership_request, verify_membership_request
|
13
|
+
# list_membership_invitation, create_membership_invitation,
|
14
|
+
# destroy_membership_invitation, verify_membership_invitation
|
15
|
+
|
16
|
+
%w(membership membership_request membership_invitation).each do |type|
|
17
|
+
%w(list_members_for list_groups_for create destroy verify).each do |action|
|
18
|
+
define_method "#{action}_#{type}" do
|
19
|
+
send("#{action}", "Adhocracy::#{type.camelize}".constantize)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def list_members_for(membership_class)
|
26
|
+
membership_class.where(group: params[:group]).includes(:member).
|
27
|
+
collect { |membership| membership.member }
|
28
|
+
end
|
29
|
+
|
30
|
+
def list_groups_for(membership_class)
|
31
|
+
membership_class.where(member: params[:member]).includes(:group).
|
32
|
+
collect { |membership| membership.group }
|
33
|
+
end
|
34
|
+
|
35
|
+
def create(membership_class)
|
36
|
+
membership_class.create(params)
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy(membership_class)
|
40
|
+
membership = membership_class.find_by(params)
|
41
|
+
return false if membership.nil?
|
42
|
+
membership.destroy
|
43
|
+
end
|
44
|
+
|
45
|
+
def verify(membership_class)
|
46
|
+
membership_class.where(params).exists?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/adhocracy/version.rb
CHANGED
data/lib/adhocracy.rb
CHANGED
@@ -23,6 +23,7 @@ module Dummy
|
|
23
23
|
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
24
24
|
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
25
25
|
# config.i18n.default_locale = :de
|
26
|
+
config.i18n.enforce_available_locales = true
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(version: 20140306214620) do
|
15
|
+
|
16
|
+
# These are extensions that must be enabled in order to support this database
|
17
|
+
enable_extension "plpgsql"
|
18
|
+
|
19
|
+
create_table "adhocracy_membership_invitations", force: true do |t|
|
20
|
+
t.string "member_type"
|
21
|
+
t.integer "member_id"
|
22
|
+
t.string "group_type"
|
23
|
+
t.integer "group_id"
|
24
|
+
t.boolean "pending", default: true, null: false
|
25
|
+
t.boolean "accepted", default: false, null: false
|
26
|
+
t.boolean "declined", default: false, null: false
|
27
|
+
t.datetime "created_at"
|
28
|
+
t.datetime "updated_at"
|
29
|
+
end
|
30
|
+
|
31
|
+
add_index "adhocracy_membership_invitations", ["member_id", "member_type"], name: "adhocracy_membership_invitations_on_member", using: :btree
|
32
|
+
|
33
|
+
create_table "adhocracy_membership_requests", force: true do |t|
|
34
|
+
t.string "member_type"
|
35
|
+
t.integer "member_id"
|
36
|
+
t.string "group_type"
|
37
|
+
t.integer "group_id"
|
38
|
+
t.boolean "pending", default: true, null: false
|
39
|
+
t.boolean "accepted", default: false, null: false
|
40
|
+
t.boolean "declined", default: false, null: false
|
41
|
+
t.datetime "created_at"
|
42
|
+
t.datetime "updated_at"
|
43
|
+
end
|
44
|
+
|
45
|
+
add_index "adhocracy_membership_requests", ["member_id", "member_type"], name: "adhocracy_membership_requests_on_member", using: :btree
|
46
|
+
|
47
|
+
create_table "adhocracy_memberships", force: true do |t|
|
48
|
+
t.string "member_type"
|
49
|
+
t.integer "member_id"
|
50
|
+
t.string "group_type"
|
51
|
+
t.integer "group_id"
|
52
|
+
t.datetime "created_at"
|
53
|
+
t.datetime "updated_at"
|
54
|
+
end
|
55
|
+
|
56
|
+
add_index "adhocracy_memberships", ["group_id", "group_type"], name: "adhocracy_membership_invitations_on_group", using: :btree
|
57
|
+
add_index "adhocracy_memberships", ["group_id", "group_type"], name: "adhocracy_membership_requests_on_group", using: :btree
|
58
|
+
add_index "adhocracy_memberships", ["group_id", "group_type"], name: "adhocracy_memberships_on_group", using: :btree
|
59
|
+
add_index "adhocracy_memberships", ["member_id", "member_type"], name: "adhocracy_memberships_on_member", using: :btree
|
60
|
+
|
61
|
+
create_table "adhocs", force: true do |t|
|
62
|
+
end
|
63
|
+
|
64
|
+
create_table "users", force: true do |t|
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|