effective_organizations 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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