klastera 1.4.0.2 → 1.4.4

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: 2c6ed8465fe9fcf78e96af1ad4d137ecdc867cc26242e0c4aada31557668b5db
4
- data.tar.gz: 045d77f5c652c11aa1badd03c404c26b07a04ddd8d7bd7886b72ba47195d9339
3
+ metadata.gz: c15103fa238ee96065a307c2e8e4d30e99488174d0c1f6cd47cf76752998e37c
4
+ data.tar.gz: e6d79698657b081437e62238c3925e5346a4b47b17f5e4671f11bfeb7f6806a8
5
5
  SHA512:
6
- metadata.gz: 70bb42f25ded9aa221049e3d2fc25a88eb467514f562a99b5ffbc26e575a9bbf692e41af450201d82f00452f7d924e5b4f3a71409539d091ab60397de65fc379
7
- data.tar.gz: 53e3902628bfac1f1353e0d6760483df4d82a51aa4ee32066c579e23b81bdb3832ab3ef9fc79ccff94d576971958ca4d00a8920ed7860ba7df1356c894b3c2c4
6
+ metadata.gz: 3e39ddb9802da7ed9f31e320e8ac36f5f26cb2fe8a4d09065c5de22fee3851e7593b08cd7223455dfdf19a718d63a98610269c2c9702e51160834938181f47d7
7
+ data.tar.gz: 2a2f371d207ce603d3887a86cedabe5451d3edc056b5549361c46dfa0ed8a0c64aa7e4897251db7683457880c5b2868f374067690a5a9c5d34c0f92f3863f32f
@@ -8,5 +8,11 @@ module Klastera::Concerns::ClusterEntity
8
8
  end
9
9
 
10
10
  module ClassMethods
11
+ def left_join_sources_of(scope_klass)
12
+ scope_klass_arel_table = scope_klass.arel_table
13
+ scope_klass_arel_table.join(arel_table, Arel::Nodes::OuterJoin).on(
14
+ scope_klass_arel_table[:id].eq(arel_table[:entity_id]), arel_table[:entity_type].eq(scope_klass.name)
15
+ ).join_sources
16
+ end
11
17
  end
12
18
  end
@@ -14,7 +14,7 @@ module Klastera::Concerns::ClusterUser
14
14
  #
15
15
  def clusters_of(organization,and_user=nil)
16
16
  and_user_id = and_user.present? ? { users: { id: and_user } } : {}
17
- ::Cluster.eager_load(cluster_users: :user).where({ organization_id: organization }.order(order: :asc).merge(and_user_id) )
17
+ ::Cluster.eager_load(cluster_users: :user).where({ organization_id: organization }.merge(and_user_id) ).order(order: :asc)
18
18
  end
19
19
 
20
20
  ##
@@ -1,6 +1,9 @@
1
1
  module Klastera::Concerns::Clusterizable
2
2
  extend ActiveSupport::Concern
3
+
3
4
  included do
5
+ class MutipleClustersOperationError < StandardError; end
6
+
4
7
  belongs_to :cluster
5
8
 
6
9
  has_many :cluster_entities, as: :entity, class_name: Klastera::ClusterEntity
@@ -18,6 +21,10 @@ module Klastera::Concerns::Clusterizable
18
21
  end
19
22
  end
20
23
 
24
+ def allow_multiple_clusters?(default=:one)
25
+ organization.cluster_cardinality_of(self.class, default: default) == :many
26
+ end
27
+
21
28
  ##
22
29
  # This is a legacy method and we don't recommend using it.
23
30
  # Implement directly Klastera.entity_clusters_string_list instead of this method.
@@ -1,7 +1,7 @@
1
1
  module Klastera::Concerns::Organization
2
2
  extend ActiveSupport::Concern
3
3
  included do
4
-
4
+ serialize :cluster_config
5
5
  has_many :clusters
6
6
 
7
7
  validates :use_cluster_as, inclusion: { in: ::Cluster::MODES.map{|m|m.to_s}, message: I18n.t('klastera.clusters.wrong_option') }, if: proc{ use_cluster_as.present? }
@@ -11,6 +11,17 @@ module Klastera::Concerns::Organization
11
11
  self.use_cluster_as.to_s.to_sym
12
12
  end
13
13
 
14
+ def cluster_cardinality_of(entity, default: :many)
15
+ if cluster_config.is_a?(Hash)
16
+ entities_cardinality = cluster_config[:entities]&.[](:cardinality)||{}
17
+ entity = entity.to_s.to_sym
18
+ if entities_cardinality.has_key?(entity)
19
+ default = entities_cardinality[entity]
20
+ end
21
+ end
22
+ default.to_s.to_sym
23
+ end
24
+
14
25
  ##
15
26
  # Return a boolean if one of three of options was set in organization
16
27
  # As useless option you can retrieve the value passing false as argument.
@@ -0,0 +1,5 @@
1
+ class AddClusterConfigToOrganization < ActiveRecord::Migration
2
+ def change
3
+ add_column :organizations, :cluster_config, :text
4
+ end
5
+ end
@@ -7,7 +7,7 @@ module Klastera
7
7
 
8
8
  UNCLUSTERED_POSITION = 9999
9
9
  UNCLUSTERED_ENTITY = 'without_cluster'.freeze
10
- KLSTR_HELPERS = %i[ cluster_user cluster_organization cluster_list cluster_scope cluster_scope_through_of user_clusters_string_list ].freeze
10
+ KLSTR_HELPERS = %i[ cluster_user cluster_organization cluster_list cluster_scope cluster_scope_through_of user_clusters_string_list cluster_scope_left_join ].freeze
11
11
 
12
12
  class << self
13
13
 
@@ -79,9 +79,8 @@ module Klastera
79
79
  # cluster_filter_id is present when the optional_suborganization mode is on. BUT!
80
80
  # Be aware that if the cluster_filter is not present, the value of force_cluster_clause
81
81
  # will be overridden by the returned value of cannot_skip_cluster_clause? method.
82
- #
83
- def cluster_scope!(scope_klass, user, organization, cluster_filter=nil, force_cluster_clause=false)
84
- scope_klass = scope_class(scope_klass)
82
+ def should_clusterize_scope?(user, organization, cluster_filter=nil, force_cluster_clause=false)
83
+ should = false # I don't know if this is a good idea
85
84
  if organization.is_in_cluster_mode? && ( cluster_filter.present? || force_cluster_clause = user.cannot_skip_cluster_clause? ) # yes, this is an assignation
86
85
  cluster_ids = []
87
86
  # Set another variable as array to get the cluster id(s)
@@ -92,15 +91,27 @@ module Klastera
92
91
  end
93
92
  # We will avoid the query unless cluster_ids is having values OR force_cluster_clause is set (see method description)
94
93
  if cluster_ids.present? || force_cluster_clause
95
- scope_klass = scope_klass.eager_load(:organization,cluster_entities: :cluster)
96
94
  # We add the unclustered if the value of cluster_filter have the special without_cluster string or as method description says
97
95
  if cluster_ids.delete(UNCLUSTERED_ENTITY) || ( force_cluster_clause && organization.optional_suborganization_mode? )
98
96
  cluster_ids << nil
99
97
  end
100
- scope_klass = scope_klass.where( cluster_entities: { cluster_id: cluster_ids } )
98
+ should = true
101
99
  end
102
100
  end
103
- scope_klass.where(organization_id: organization)
101
+ yield(should,cluster_ids)
102
+ end
103
+
104
+ #
105
+ # The cleanest and fast way to clusterize a entity!
106
+ #
107
+ def cluster_scope!(scope_klass, user, organization, cluster_filter=nil, force_cluster_clause=false)
108
+ scope = scope_class(scope_klass)
109
+ should_clusterize_scope?(user,organization,cluster_filter,force_cluster_clause) do |should,cluster_ids|
110
+ if should
111
+ scope = scope.eager_load(:organization,cluster_entities: :cluster).where( cluster_entities: { cluster_id: cluster_ids } )
112
+ end
113
+ end
114
+ scope.where(organization_id: organization)
104
115
  end
105
116
 
106
117
 
@@ -110,7 +121,7 @@ module Klastera
110
121
  unclusterized_scope = scope_class(scope_klass)
111
122
 
112
123
  if organization.is_in_cluster_mode? && ( force_cluster_clause || user.cannot_skip_cluster_clause? )
113
- unclusterized_scope = unclusterized_scope.joins(relation => :cluster_entities)
124
+ unclusterized_scope = unclusterized_scope.joins(relation).joins(Klastera::ClusterEntity.left_join_sources_of(cluster_entity_klass))
114
125
  end
115
126
 
116
127
  if scope_klass.respond_to?(:organization)
@@ -152,6 +163,20 @@ module Klastera
152
163
 
153
164
  [ kluster_scope, grouped_cluster_scope ]
154
165
  end
166
+
167
+ #
168
+ # A helper that returns a CLUSTER SCOPE to build queries that need explicit LEFT OUTER JOIN clause,
169
+ # instead of the default INNER JOIN provide by ActiveRecord's joins method
170
+ #
171
+ def cluster_scope_left_join!(scope_klass,organization)
172
+ cluster_entities_arel_table = Klastera::ClusterEntity.arel_table
173
+ cluster_arel_table = ::Cluster.arel_table
174
+ cluster_entities_cluster = cluster_entities_arel_table.join(cluster_arel_table, Arel::Nodes::OuterJoin).on(
175
+ cluster_entities_arel_table[:cluster_id].eq(cluster_arel_table[:id]),
176
+ ).join_sources
177
+
178
+ scope_class(scope_klass).where(organization_id: organization).joins(Klastera::ClusterEntity.left_join_sources_of(scope_klass)).joins(cluster_entities_cluster)
179
+ end
155
180
  end
156
181
 
157
182
  ##################################################################################################################################################
@@ -193,6 +218,10 @@ module Klastera
193
218
  Klastera.user_clusters_string_list!(cluster_user, cluster_organization, object_entity.try(:cluster_entities), separator, attribute)
194
219
  end
195
220
 
221
+ def cluster_scope_left_join(scope_klass)
222
+ Klastera.cluster_scope_left_join!(scope_klas,cluster_organization)
223
+ end
224
+
196
225
  included do
197
226
  Klastera::KLSTR_HELPERS.each do |action|
198
227
  if respond_to?(:helper_method)
@@ -1,3 +1,3 @@
1
1
  module Klastera
2
- VERSION = "1.4.0.2"
2
+ VERSION = "1.4.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: klastera
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0.2
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gino Barahona
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-31 00:00:00.000000000 Z
11
+ date: 2020-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -93,6 +93,7 @@ files:
93
93
  - db/migrate/20200330010551_create_klastera_cluster_users.rb
94
94
  - db/migrate/20200330221601_add_order_field_to_clusters.rb
95
95
  - db/migrate/20200518142609_create_klastera_cluster_entities.rb
96
+ - db/migrate/20200908180057_add_cluster_config_to_organization.rb
96
97
  - lib/klastera.rb
97
98
  - lib/klastera/engine.rb
98
99
  - lib/klastera/version.rb