effective_organizations 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bcbee46f5235da4b9d6fa04d84daab02383cfe373532138dc6ec601fc3110ced
4
- data.tar.gz: a400d6e2ecec13c3a98b6e58beda724471628e9262100dbeb5f9b414940fd417
3
+ metadata.gz: 1d1867153f3a3fd958c18fd26c374fba6a439516480ffac3825aabdbc5dadf5f
4
+ data.tar.gz: 14bf4b503c58169387f886c3781bb2843f51cf90fedd3994eb5333850abc8461
5
5
  SHA512:
6
- metadata.gz: c7a6df31f4b94032905653c0ba44489ba4ac87b47f7e48e488726e4e9c9d8a26b41a02211f94f277ce91c871765ef0bce77a33ebf4aa0dbaef9a5f71ddf83520
7
- data.tar.gz: 84dfedd0a963e6080faac3e7e8553e7739d9179d9e13d4aabb251516848fae840668d02c627884d6acb78d12588d5a221a3d287ee0d63d9b75f7f4b0389dce30
6
+ metadata.gz: 7139213c4c010b19cb733d50c1b042fb25f23246c1c1295ca23fe05c1f17e9705f64476b46acbe19833b0b13c7ade72918207b0fceab50fc62586163c332ed92
7
+ data.tar.gz: ee0dd2280a17fd2ba168a257a875608bf8027b7548db9d3482728f54e4b3898087645d212f860e8307eb0aa8fbfdbe55626327608858ad8aa6911365ad30d280
data/README.md CHANGED
@@ -71,16 +71,85 @@ Add a link to the admin menu:
71
71
 
72
72
  All authorization checks are handled via the effective_resources gem found in the `config/initializers/effective_resources.rb` file.
73
73
 
74
+ ## Effective Roles
75
+
76
+ This gem works with effective roles for the representative roles.
77
+
78
+ Configure your `config/initializers/effective_roles.rb` something like this:
79
+
80
+ ```
81
+ EffectiveRoles.setup(:caaa) do |config|
82
+ config.roles = [:admin, :reserved, :owner, :billing] # Only add to the end of this array. Never prepend roles.
83
+
84
+ # config.role_descriptions
85
+ # ========================
86
+ # This setting configures the text that is displayed by form helpers (see README.md)
87
+
88
+ config.role_descriptions = {
89
+ 'User' => {
90
+ # User roles
91
+ admin: 'can log in to the /admin section of the website. full access to everything.',
92
+ },
93
+ 'Effective::Representative' => {
94
+ owner: 'the owner. full access to everything.',
95
+ billing: 'the billing contact. full access to everything.'
96
+ }
97
+ }
98
+
99
+ # config.assignable_roles
100
+ # Which roles can be assigned by whom
101
+ # =======================
102
+ # When current_user is passed into a form helper function (see README.md)
103
+ # this setting determines which roles that current_user may assign
104
+ config.assignable_roles = {
105
+ 'User' => { admin: [:admin] },
106
+
107
+ 'Effective::Representative' => {
108
+ admin: [:owner, :billing],
109
+ owner: [:owner, :billing],
110
+ billing: [:billing]
111
+ }
112
+ }
113
+ end
114
+ ```
115
+
116
+
74
117
  ## Permissions
75
118
 
76
119
  The permissions you actually want to define are as follows (using CanCan):
77
120
 
78
121
  ```ruby
122
+ if user.persisted?
123
+ can :index, EffectiveOrganizations.Organization
124
+ can(:show, EffectiveOrganizations.Organization) { |organization| user.organizations.include?(organization) }
125
+
126
+ can([:edit, :update], EffectiveOrganizations.Organization) do |organization|
127
+ rep = user.representative(organization: organization)
128
+ rep && (rep.is?(:owner) || rep.is?(:billing))
129
+ end
130
+
131
+ can :index, Effective::Representative
132
+ can(:new, Effective::Representative)
133
+
134
+ can([:create, :edit, :update], Effective::Representative) do |representative|
135
+ rep = user.representative(organization: representative.organization)
136
+ rep && (rep.is?(:owner) || rep.is?(:billing))
137
+ end
138
+
139
+ can(:destroy, Effective::Representative) do |representative|
140
+ allowed = !(representative.is?(:owner) || representative.is?(:billing))
141
+ rep = user.representative(organization: representative.organization)
142
+
143
+ allowed && rep && (rep.is?(:owner) || rep.is?(:billing))
144
+ end
145
+ end
79
146
 
80
147
  if user.admin?
81
148
  can :admin, :effective_organizations
82
- can :manage, Effective::Organization
83
- can :manage, Effective::Representative
149
+ can(crud, EffectiveOrganizations.Organization)
150
+
151
+ can(crud - [:destroy], Effective::Representative)
152
+ can(:destroy, Effective::Representative) { |rep| !rep.is?(:owner) }
84
153
  end
85
154
  ```
86
155
 
@@ -6,7 +6,11 @@ module EffectiveOrganizationsOrganization
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module Base
9
- def effective_organizations_organization
9
+ def effective_organizations_organization(users_source_type: nil)
10
+ @effective_organizations_organization_opts = {
11
+ users_source_type: users_source_type
12
+ }
13
+
10
14
  include ::EffectiveOrganizationsOrganization
11
15
  end
12
16
  end
@@ -20,7 +24,7 @@ module EffectiveOrganizationsOrganization
20
24
  end
21
25
 
22
26
  included do
23
- log_changes(except: :representatives) if respond_to?(:log_changes)
27
+ log_changes(except: [:representatives, :users]) if respond_to?(:log_changes)
24
28
 
25
29
  # rich_text_body
26
30
  # has_many_rich_texts
@@ -28,7 +32,8 @@ module EffectiveOrganizationsOrganization
28
32
  has_many :representatives, -> { Effective::Representative.sorted },
29
33
  class_name: 'Effective::Representative', inverse_of: :organization, dependent: :delete_all
30
34
 
31
- has_many :users, through: :representatives
35
+ has_many :users, through: :representatives,
36
+ source_type: (@effective_organizations_organization_opts[:users_source_type] || (name.start_with?('Effective') ? '::User' : "#{name.split('::').first}::Organization"))
32
37
 
33
38
  effective_resource do
34
39
  title :string
@@ -6,7 +6,11 @@ module EffectiveOrganizationsUser
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module Base
9
- def effective_organizations_user
9
+ def effective_organizations_user(organizations_source_type: nil)
10
+ @effective_organizations_user_opts = {
11
+ organizations_source_type: organizations_source_type
12
+ }
13
+
10
14
  include ::EffectiveOrganizationsUser
11
15
  end
12
16
  end
@@ -21,7 +25,8 @@ module EffectiveOrganizationsUser
21
25
  class_name: 'Effective::Representative', inverse_of: :user, dependent: :delete_all
22
26
 
23
27
  # App scoped
24
- has_many :organizations, through: :representatives
28
+ has_many :organizations, through: :representatives,
29
+ source_type: @effective_organizations_user_opts[:organizations_source_type] || "#{name.split('::').first}::Organization"
25
30
  end
26
31
 
27
32
  def representative(organization:)
@@ -3,5 +3,6 @@ module Effective
3
3
  self.table_name = EffectiveOrganizations.organizations_table_name.to_s
4
4
 
5
5
  effective_organizations_organization
6
+
6
7
  end
7
8
  end
@@ -7,9 +7,10 @@ module Effective
7
7
 
8
8
  log_changes(to: :organization) if respond_to?(:log_changes)
9
9
 
10
- belongs_to :organization, counter_cache: true
10
+ belongs_to :organization, polymorphic: true, counter_cache: true
11
11
  belongs_to :user, polymorphic: true
12
12
 
13
+ accepts_nested_attributes_for :organization
13
14
  accepts_nested_attributes_for :user
14
15
 
15
16
  effective_resource do
@@ -28,8 +29,8 @@ module Effective
28
29
  validates :organization, presence: true
29
30
  validates :user, presence: true
30
31
 
31
- validates :user_id, if: -> { user_id && user_type && organization_id },
32
- uniqueness: { scope: [:organization_id], message: 'already belongs to this organization' }
32
+ validates :user_id, if: -> { user_id && user_type && organization_id && organization_type },
33
+ uniqueness: { scope: [:organization_id, :organization_type], message: 'already belongs to this organization' }
33
34
 
34
35
  def to_s
35
36
  user.to_s
@@ -40,5 +41,10 @@ module Effective
40
41
  self.user = user_type.constantize.new(attributes)
41
42
  end
42
43
 
44
+ def build_organization(attributes = {})
45
+ raise('please assign organization_type first') if organization_type.blank?
46
+ self.organization = organization_type.constantize.new(attributes)
47
+ end
48
+
43
49
  end
44
50
  end
@@ -0,0 +1,6 @@
1
+ - categories = EffectiveOrganizations.Organization.categories
2
+
3
+ - if categories.present?
4
+ = f.select :category, categories, required: true
5
+
6
+ = f.text_field :title
@@ -1,10 +1,5 @@
1
1
  = effective_form_with(model: [:admin, organization], engine: true) do |f|
2
- - categories = EffectiveOrganizations.Organization.categories
3
-
4
- - if categories.present?
5
- = f.select :category, categories, required: true
6
-
7
- = f.text_field :title
2
+ = render 'admin/organizations/fields', f: f
8
3
 
9
4
  = effective_submit(f)
10
5
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  - if f.object.new_record?
9
9
  - unless inline_datatable? && inline_datatable.attributes[:organization_id].present?
10
- = f.select :organization_id, EffectiveOrganizations.Organization.sorted
10
+ = f.select :organization, { 'Organizations' => EffectiveOrganizations.Organization.sorted }, polymorphic: true
11
11
 
12
12
  = f.checks :roles, EffectiveRoles.roles_collection(f.object)
13
13
 
@@ -0,0 +1,6 @@
1
+ - categories = EffectiveOrganizations.Organization.categories
2
+
3
+ - if categories.present?
4
+ = f.select :category, categories, required: true
5
+
6
+ = f.text_field :title
@@ -1,12 +1,7 @@
1
1
  - url = (organization.persisted? ? effective_organizations.organization_path(organization) : effective_organizations.organizations_path)
2
2
 
3
3
  = effective_form_with(model: organization, url: url) do |f|
4
- - categories = EffectiveOrganizations.Organization.categories
5
-
6
- - if categories.present?
7
- = f.select :category, categories, required: true
8
-
9
- = f.text_field :title
4
+ = render 'effective/organizations/fields', f: f
10
5
 
11
6
  = f.submit
12
7
 
@@ -4,10 +4,11 @@
4
4
  = f.hidden_field :user_id
5
5
  = f.hidden_field :user_type
6
6
  = f.hidden_field :organization_id
7
+ = f.hidden_field :organization_type
7
8
 
8
9
  - if f.object.new_record?
9
10
  - unless inline_datatable? && inline_datatable.attributes[:organization_id].present?
10
- = f.select :organization_id, EffectiveOrganizations.Organization.sorted
11
+ = f.select :organization, { 'Organizations' => EffectiveOrganizations.Organization.sorted }, polymorphic: true
11
12
 
12
13
  = f.checks :roles, EffectiveRoles.roles_collection(f.object)
13
14
 
@@ -18,7 +18,6 @@ class CreateEffectiveOrganizations < ActiveRecord::Migration[6.0]
18
18
  # Representatives
19
19
  create_table :representatives do |t|
20
20
  t.integer :organization_id
21
- t.string :organization_type
22
21
 
23
22
  t.integer :user_id
24
23
  t.string :user_type
@@ -29,7 +28,7 @@ class CreateEffectiveOrganizations < ActiveRecord::Migration[6.0]
29
28
  t.datetime :created_at
30
29
  end
31
30
 
32
- add_index :representatives, [:organization_id, :organization_type]
31
+ add_index :representatives, [:organization_id]
33
32
  add_index :representatives, [:user_id, :user_type]
34
33
 
35
34
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveOrganizations
2
- VERSION = '0.0.2'.freeze
2
+ VERSION = '0.0.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_organizations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-10 00:00:00.000000000 Z
11
+ date: 2021-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: effective_roles
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: sqlite3
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -178,11 +192,13 @@ files:
178
192
  - app/models/concerns/effective_organizations_user.rb
179
193
  - app/models/effective/organization.rb
180
194
  - app/models/effective/representative.rb
195
+ - app/views/admin/organizations/_fields.html.haml
181
196
  - app/views/admin/organizations/_form.html.haml
182
197
  - app/views/admin/organizations/_form_organization.html.haml
183
198
  - app/views/admin/representatives/_form.html.haml
184
199
  - app/views/admin/representatives/_user_fields.html.haml
185
200
  - app/views/effective/organizations/_dashboard.html.haml
201
+ - app/views/effective/organizations/_fields.html.haml
186
202
  - app/views/effective/organizations/_form.html.haml
187
203
  - app/views/effective/organizations/_form_organization.html.haml
188
204
  - app/views/effective/representatives/_form.html.haml