klastera 1.1.6.1 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/klastera/clusters.css.scss +11 -0
  3. data/app/models/klastera/cluster_entity.rb +5 -0
  4. data/app/models/klastera/concerns/cluster_entity.rb +12 -0
  5. data/app/models/klastera/concerns/cluster_user.rb +7 -7
  6. data/app/models/klastera/concerns/clusterizable.rb +24 -4
  7. data/app/models/klastera/concerns/user.rb +13 -8
  8. data/app/views/layouts/klastera/_cluster_entity_fields.html.erb +10 -0
  9. data/app/views/layouts/klastera/_cluster_filter.html.erb +1 -1
  10. data/app/views/layouts/klastera/_cluster_user_fields.html.erb +2 -2
  11. data/app/views/layouts/klastera/_nested_cluster_entity.html.erb +41 -0
  12. data/app/views/layouts/klastera/_nested_cluster_user.html.erb +18 -16
  13. data/config/locales/es.yml +2 -0
  14. data/db/migrate/20200518142609_create_klastera_cluster_entities.rb +8 -0
  15. data/lib/klastera.rb +109 -26
  16. data/lib/klastera/version.rb +1 -1
  17. data/lib/tasks/klastera_tasks.rake +23 -0
  18. metadata +9 -76
  19. data/app/assets/stylesheets/klastera/application.css +0 -15
  20. data/app/assets/stylesheets/klastera/clusters.css +0 -4
  21. data/app/assets/stylesheets/scaffold.css +0 -56
  22. data/test/dummy/README.rdoc +0 -28
  23. data/test/dummy/Rakefile +0 -6
  24. data/test/dummy/app/assets/javascripts/application.js +0 -13
  25. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  26. data/test/dummy/app/controllers/application_controller.rb +0 -5
  27. data/test/dummy/app/helpers/application_helper.rb +0 -2
  28. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  29. data/test/dummy/bin/bundle +0 -3
  30. data/test/dummy/bin/rails +0 -4
  31. data/test/dummy/bin/rake +0 -4
  32. data/test/dummy/bin/setup +0 -29
  33. data/test/dummy/config.ru +0 -4
  34. data/test/dummy/config/application.rb +0 -26
  35. data/test/dummy/config/boot.rb +0 -5
  36. data/test/dummy/config/database.yml +0 -1
  37. data/test/dummy/config/environment.rb +0 -5
  38. data/test/dummy/config/environments/development.rb +0 -41
  39. data/test/dummy/config/environments/production.rb +0 -79
  40. data/test/dummy/config/environments/test.rb +0 -42
  41. data/test/dummy/config/initializers/assets.rb +0 -11
  42. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  43. data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  44. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  45. data/test/dummy/config/initializers/inflections.rb +0 -16
  46. data/test/dummy/config/initializers/mime_types.rb +0 -4
  47. data/test/dummy/config/initializers/session_store.rb +0 -3
  48. data/test/dummy/config/initializers/to_time_preserves_timezone.rb +0 -10
  49. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  50. data/test/dummy/config/locales/en.yml +0 -23
  51. data/test/dummy/config/routes.rb +0 -4
  52. data/test/dummy/config/secrets.yml +0 -22
  53. data/test/dummy/public/404.html +0 -67
  54. data/test/dummy/public/422.html +0 -67
  55. data/test/dummy/public/500.html +0 -66
  56. data/test/dummy/public/favicon.ico +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d99d98acb9cb221ce9fad3b71ba9ae14aec4aa13a2a8a09438ace17a56e4187
4
- data.tar.gz: c6f76aea020ba9562ec5a7256c38663612ca3f5da4a8ebb3e96f6de16f4057f3
3
+ metadata.gz: f1d1b4ee48b85521c4f7b9b085877a8138ac3f267b275cd09974102d1c55e488
4
+ data.tar.gz: ff0bd6762b86cc3aa0bcf0f97302322175f2dca25797f7f4a413cd8b0a32f01c
5
5
  SHA512:
6
- metadata.gz: c975d640c103a49604984952afc7f3e3fe7a568f6db070a7afdbb59301dba0d4d13e41f02dd737ccf7bbad9a4673e61b8bcd460a5c929db818f9281907b8886d
7
- data.tar.gz: c39540a4125b3be5302df5af564758bcb04f1faa68aed596f9617aeaf17021b8bed569890d213c60209dcb64ef631dc3c296b2fa460b61ae230d1c8be85c4e06
6
+ metadata.gz: e3c25e15d17ce5a8f3a3ac621efff40ee0056794dea067c5db85b19b2ecca87badae22632f0d2358ddff397bcabdd1e0f1fe54a1795f9f6fc0a1806fc9a6d88d
7
+ data.tar.gz: b0f03f444cc382dea3f8988e015eb88635b4b707344896a2f07063b0d1a996d5f939c37fed19a08bb3b9a4eee3c6e3a2aeb3b7ad75e264c156d795fc3845d03a
@@ -0,0 +1,11 @@
1
+ .nested-cluster-user,
2
+ .nested-cluster-entity {
3
+ .panel {
4
+ margin: 0;
5
+ border-bottom: 0;
6
+ .panel-heading {
7
+ padding: 10px 12px 10px 15px;
8
+ background: none;
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ module Klastera
2
+ class ClusterEntity < ActiveRecord::Base
3
+ include Klastera::Concerns::ClusterEntity
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module Klastera::Concerns::ClusterEntity
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ self.table_name = 'cluster_entities'
6
+ belongs_to :entity, polymorphic: true
7
+ belongs_to :cluster, class_name: ::Cluster
8
+ end
9
+
10
+ module ClassMethods
11
+ end
12
+ end
@@ -10,7 +10,7 @@ module Klastera::Concerns::ClusterUser
10
10
  validates :cluster_id, presence: true
11
11
 
12
12
  scope :of, -> (user,organization) {
13
- Rails.logger.warn("DON'T USE THIS SCOPE DIRECTLY: Use ::ClusterUser.get_from class method instead!")
13
+ Rails.logger.warn("DON'T USE THIS SCOPE DIRECTLY: Use ::ClusterUser.clusters_from class method instead!")
14
14
  includes(:cluster).where(user_id: user, "clusters.organization_id": organization)
15
15
  }
16
16
  end
@@ -20,13 +20,13 @@ module Klastera::Concerns::ClusterUser
20
20
  ##
21
21
  # Returns a hash with the users with cluster relation
22
22
  #
23
- def get_user_clusters_from(organization)
23
+ def user_clusters_from(organization)
24
24
  users_hash = {}
25
25
  organization_cluster_ids = ::Cluster.of(organization).map(&:id)
26
- ::ClusterUser.includes(:user).where(cluster_id: organization_cluster_ids).each do |cluster|
27
- user_id = cluster.try(:user).try(:id) || :uncluster
28
- users_hash[user_id] ||= [];
29
- users_hash[user_id] << cluster.id
26
+ ::ClusterUser.includes(:user).where(cluster_id: organization_cluster_ids).each do |cluster_user|
27
+ user_id = cluster_user.user_id || :uncluster
28
+ users_hash[user_id] ||= []
29
+ users_hash[user_id] << cluster_user.cluster_id
30
30
  end
31
31
  users_hash
32
32
  end
@@ -35,7 +35,7 @@ module Klastera::Concerns::ClusterUser
35
35
  # Returns a Cluster::ActiveRecord_Relation
36
36
  #
37
37
  ##
38
- def get_clusters_from(user,organization)
38
+ def clusters_from(user,organization)
39
39
  clusters = []
40
40
  unless user.can_admin_clusters?
41
41
  # We could return cu.clusters but you may quering this result and a array can't handle order, where and etc.
@@ -4,16 +4,36 @@ module Klastera::Concerns::Clusterizable
4
4
  attr_accessor :lonely_cluster
5
5
  belongs_to :cluster
6
6
 
7
- validates :cluster_id, presence: true, if: proc { self.organization.required_suborganization_mode? }
7
+ has_many :cluster_entities, as: :entity, class_name: Klastera::ClusterEntity
8
+ accepts_nested_attributes_for :cluster_entities, reject_if: :all_blank, allow_destroy: true
9
+
10
+ validates :cluster_id, presence: true, if: proc { self.try(:cluster_id) && self.organization.required_suborganization_mode? }
11
+ validate :at_least_one_cluster_entity, if: proc { self.organization.required_suborganization_mode? }
8
12
 
9
13
  scope :related_clusters, ->() {
10
- includes(:cluster).where("#{self.table_name}.cluster_id IS NOT NULL")
14
+ includes(:cluster_entities).where("cluster_entities.entity_id = #{self.table_name}.id")
11
15
  }
16
+
17
+ def at_least_one_cluster_entity
18
+ if cluster_entities.length == 0 || cluster_entities.reject{|cluster_entity| cluster_entity._destroy == true}.empty?
19
+ return errors.add(:cluster_entities, I18n.t('klastera.messages.at_least_one_cluster_entity'))
20
+ end
21
+ end
22
+
23
+ def clusters_string_separated_by(separator,attribute=:name)
24
+ self.cluster_entities.map{|ce|ce.cluster.send(attribute)}.join(separator)
25
+ end
26
+
27
+ def has_one_cluster_entity
28
+ if cluster_entities.length > 1
29
+ return errors.add(:cluster_entities, I18n.t('klastera.messages.has_one_cluster_entity'))
30
+ end
31
+ end
12
32
  end
13
33
 
14
34
  module ClassMethods
15
- def cluster_params
16
- [ :cluster_id, :lonely_cluster ]
35
+ def cluster_entity_params
36
+ [ :cluster_id, :lonely_cluster, { cluster_entities_attributes: [:id, :cluster_id, :_destroy] } ]
17
37
  end
18
38
  end
19
39
  end
@@ -33,20 +33,25 @@ module Klastera::Concerns::User
33
33
  self.organization.is_in_cluster_mode? && ( self.is_a_cluster_admin? || self.is_a_cluster_root? )
34
34
  end
35
35
 
36
+ #
36
37
  # We will try to create a cluster_user record whether
37
- # the organization is using force mode (if cluster_id isn't present,
38
- # will raise a validation error) or cluster_id is present
39
- # (on organizations with show/use mode).
40
- def try_to_clusterify!(role,cluster_id)
38
+ # the organization is using force mode (if cluster_id isn't present, it will raise a validation error)
39
+ # or
40
+ # cluster_id is present (on show/use mode organizations).
41
+ #
42
+ def try_to_clusterify!(role,cluster_ids)
41
43
  if self.try(:organization).try(:is_in_cluster_mode?)
42
44
  self.cluster_role = role
43
- if self.try(:organization).try(:required_suborganization_mode?) || cluster_id.present?
44
- self.cluster_users_attributes = {
45
- DateTime.now.to_i => {
45
+ if self.try(:organization).try(:required_suborganization_mode?) || cluster_ids.present?
46
+ timestamp = DateTime.now.to_i
47
+ nested_attributes = {}
48
+ cluster_ids.each do |cluster_id|
49
+ nested_attributes["#{cluster_id}_#{timestamp}"] = {
46
50
  cluster_id: cluster_id,
47
51
  _destroy: false
48
52
  }
49
- }
53
+ end
54
+ self.cluster_users_attributes = nested_attributes
50
55
  end
51
56
  end
52
57
  end
@@ -0,0 +1,10 @@
1
+ <tr class="nested-fields">
2
+ <td class="field">
3
+ <%= f.select :cluster_id, cluster_clusters.map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
4
+ </td>
5
+ <td class="action vertical-align-middle text-center" width="44">
6
+ <%= link_to_remove_association f, class: 'btn btn-danger btn-xs text-danger' do %>
7
+ <i class="fa fa-trash"></i>
8
+ <% end %>
9
+ </td>
10
+ </tr>
@@ -4,7 +4,7 @@
4
4
  <%= button_tag(t('klastera.actions.filter'), class: 'btn btn-primary btn-sm float-right', data: { disable_with: "<i class='fa fa-spinner spin'></i>" }) %>
5
5
  </div>
6
6
 
7
- <%=yield(f)%>
7
+ <%=yield(f) if block_given? %>
8
8
 
9
9
  <% if cluster_organization.is_in_cluster_mode? %>
10
10
  <% cluster_collection = cluster_clusters.map{|c|[c.name,(c.id||c.nid)]} %>
@@ -1,8 +1,8 @@
1
1
  <tr class="nested-fields">
2
2
  <td class="field">
3
3
  <%= f.select :cluster_id, @user.organization.clusters.map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
4
- </td>
5
- <td class="action vertical-align-middle" width="44">
4
+ </td>
5
+ <td class="action vertical-align-middle text-center" width="44">
6
6
  <%= link_to_remove_association f, class: 'btn btn-danger btn-xs text-danger' do %>
7
7
  <i class="fa fa-trash"></i>
8
8
  <% end %>
@@ -0,0 +1,41 @@
1
+ <% if cluster_organization.is_in_cluster_mode? && cluster_user.can_admin_clusters? %>
2
+ <div class="col-xs-12">
3
+ <% if hide_title||=false %>
4
+ <div class="form-group file required <%=f.object.class.name.parameterize%>_cluster_entity<%=' has-error' if f.object.errors.has_key?(:cluster_entities)%>">
5
+ <label class="text" for="<%=f.object.class.name.parameterize%>_cluster_entity">
6
+ <%=t('klastera.clusters.title')%>
7
+ <% if cluster_organization.required_suborganization_mode? %>
8
+ <abbr title="required">*</abbr>
9
+ <% end %>
10
+ </label>
11
+ <% end %>
12
+
13
+ <div class="nested-cluster-entity">
14
+ <div class="panel panel-default">
15
+ <div class="panel-heading<%=' custom-required' if cluster_organization.required_suborganization_mode? %>">
16
+ <h4 class="panel-title">
17
+ <% unless hide_title||=false %>
18
+ <div class="float-left" style="line-height: 20px"><%=t('klastera.clusters.title')%></div>
19
+ <% end %>
20
+ <%= link_to_add_association f, :cluster_entities, partial: 'layouts/klastera/cluster_entity_fields', data: { 'association-insertion-node': :'tbody.cluster-entity-rows', 'association-insertion-method': :append }, class: 'btn btn-success btn-xs float-right color-white' do %>
21
+ <i class="fa fa-plus"></i>
22
+ <% end %>
23
+ <div class="clearfix"></div>
24
+ </h4>
25
+ </div>
26
+ <table id="cluster-entities" class="table table-striped">
27
+ <tbody class="cluster-entity-rows">
28
+ <%= f.fields_for :cluster_entities do |cluster_entity|%>
29
+ <%= render 'layouts/klastera/cluster_entity_fields', f: cluster_entity %>
30
+ <% end %>
31
+ </body>
32
+ </table>
33
+ </div>
34
+ </div>
35
+
36
+ <% if hide_title||=false %>
37
+ <div class="invalid-feedback"><%=f.object.try(:errors)&.[](:cluster_entities).try(:first)%></div>
38
+ </div>
39
+ <% end %>
40
+ </div>
41
+ <% end %>
@@ -1,20 +1,22 @@
1
1
  <% if @user.try(:is_a_cluster_user?) %>
2
- <div class="panel panel-default">
3
- <div class="panel-heading">
4
- <h4 class="panel-title">
5
- <div class="float-left" style="line-height: 20px"><%=t('klastera.clusters.title')%></div>
6
- <%= link_to_add_association f, :cluster_users, partial: 'layouts/klastera/cluster_user_fields', data: { 'association-insertion-node': :'tbody.cluster-user-rows', 'association-insertion-method': :append }, class: 'btn btn-success btn-xs float-right color-white' do %>
7
- <i class="fa fa-plus"></i>
8
- <% end %>
9
- <div class="clearfix">
10
- </h4>
2
+ <div class="nested-cluster-user">
3
+ <div class="panel panel-default">
4
+ <div class="panel-heading">
5
+ <h4 class="panel-title">
6
+ <div class="float-left" style="line-height: 20px"><%=t('klastera.clusters.title')%></div>
7
+ <%= link_to_add_association f, :cluster_users, partial: 'layouts/klastera/cluster_user_fields', data: { 'association-insertion-node': :'tbody.cluster-user-rows', 'association-insertion-method': :append }, class: 'btn btn-success btn-xs float-right color-white' do %>
8
+ <i class="fa fa-plus"></i>
9
+ <% end %>
10
+ <div class="clearfix"></div>
11
+ </h4>
12
+ </div>
13
+ <table id="cluster-users" class="table table-striped">
14
+ <tbody class="cluster-user-rows">
15
+ <%= f.fields_for :cluster_users do |cluster_user|%>
16
+ <%= render 'layouts/klastera/cluster_user_fields', f: cluster_user %>
17
+ <% end %>
18
+ </body>
19
+ </table>
11
20
  </div>
12
- <table id="cluster-users" class="table">
13
- <tbody class="cluster-user-rows">
14
- <%= f.fields_for :cluster_users do |cluster_user|%>
15
- <%= render 'layouts/klastera/cluster_user_fields', f: cluster_user %>
16
- <% end %>
17
- </body>
18
- </table>
19
21
  </div>
20
22
  <% end %>
@@ -57,6 +57,8 @@ es:
57
57
  created: Creado
58
58
  updated: Actualizado
59
59
  messages:
60
+ has_one_cluster_entity: Está permitido agregar un sólo cluster
61
+ at_least_one_cluster_entity: Debe agregar al menos un cluster
60
62
  record_action_successfully: Registro %{a} exitosamente
61
63
  cant_delete_the_last_record_in_required_suborganization_mode: No se puede eliminar el único cluster de esta organización
62
64
  new_cluster_id:
@@ -0,0 +1,8 @@
1
+ class CreateKlasteraClusterEntities < ActiveRecord::Migration
2
+ def change
3
+ create_table :cluster_entities do |t|
4
+ t.integer :cluster_id, index: true
5
+ t.references :entity, polymorphic: true, index: true
6
+ end
7
+ end
8
+ end
@@ -3,41 +3,117 @@ require "klastera/engine"
3
3
  module Klastera
4
4
  mattr_accessor :organization_class
5
5
 
6
- class RelatedClusterEntityComplianceError < StandardError; end
7
6
  extend ActiveSupport::Concern
8
7
 
9
8
  class << self
10
9
 
10
+ def set_cluster_entities_attributes!(entity,array_cluster_ids)
11
+ cluster_entities_attributes = {}
12
+ entity_cluster_entities = entity.try(:cluster_entities) || []
13
+ entity_clusters = entity_cluster_entities.map(&:cluster_id).sort
14
+ array_cluster_ids = array_cluster_ids.map(&:id).sort
15
+ if array_cluster_ids != entity_clusters
16
+ now = DateTime.now
17
+ entity_cluster_entities.each_with_index do |ec,index|
18
+ remove_cluster = true
19
+ if array_cluster_ids.include?(ec.cluster_id)
20
+ remove_cluster = false
21
+ array_cluster_ids.delete(ec.cluster_id)
22
+ end
23
+ cluster_entities_attributes[index] = { id: ec.id, cluster_id: ec.cluster_id, _destroy: remove_cluster }
24
+ end
25
+ array_cluster_ids.each_with_index do |cluster_id,index|
26
+ cluster_entities_attributes[now.to_i+index] = { cluster_id: cluster_id, _destroy: false }
27
+ end
28
+ end
29
+ cluster_entities_attributes
30
+ end
31
+
32
+ #
33
+ # I like to wrap methods
34
+ #
35
+ def cluster_scope_filtered!(scope,cluster_id,user,organization,includes=[])
36
+ self.filter_clusterized_collection_with!(
37
+ organization,
38
+ cluster_id,
39
+ self.cluster_scope!(user,organization,scope,includes)
40
+ )
41
+ end
42
+
43
+ #
44
+ # In order to this works, active_record_collection argument
45
+ # should be passed through cluster_scope! method before.
46
+ #
47
+ def filter_clusterized_collection_with!(cluster_organization,cluster_id,active_record_collection)
48
+ if cluster_organization.is_in_cluster_mode?
49
+ if cluster_id.present?
50
+ cluster_array = [cluster_id]
51
+ # Based on force/use/show definition we don't really need this validation.
52
+ # A force cluster organization won't return an entity out of a cluster, but
53
+ # we don't know if the clusterized entities are fully definition-compliant.
54
+ cluster_array << nil if cluster_organization.optional_suborganization_mode?
55
+ active_record_collection = active_record_collection.joins(:cluster_entities).where("cluster_entities.cluster_id": cluster_array)
56
+ end
57
+ # you may use a block only with clusterizable data
58
+ yield(active_record_collection) if block_given?
59
+ end
60
+ active_record_collection
61
+ end
62
+
63
+ #
64
+ #
65
+ #
66
+ def set_collection_before_group_by_entity!(cluster_organization,active_record_collection,model_class,entity_params)
67
+ entity_params_keys = [:entity_name,:entity_attribute,:entity_id,:entity_id_attribute,:unamed]
68
+ entity_params = entity_params.slice(*entity_params_keys).values
69
+ if model_class.try(:reflections).try(:keys).try(:include?,entity_params[0])
70
+ entity_params << "#{entity_params[0]}_id".to_sym
71
+ if entity_params[0] == 'cluster'
72
+ entity_params << :unclustered if cluster_organization.is_in_cluster_mode?
73
+ active_record_collection = Klastera.filter_clusterized_collection_with!(
74
+ cluster_organization,
75
+ entity_params[2],
76
+ active_record_collection
77
+ )
78
+ end
79
+ yield(
80
+ active_record_collection,
81
+ entity_params_keys.zip(entity_params).to_h)
82
+ end
83
+ end
84
+
11
85
  ##
12
86
  # Returns a ::Cluster::ActiveRecord_Relation from a given scope
13
87
  #
14
88
  def clusters_from!(user,organization,scope,includes=[])
15
- _scope_result = scope.respond_to?(:map) ? scope : cluster_scope!(user,organization,scope,includes)
16
- ::Cluster.where(id: _scope_result.related_clusters.map(&:cluster_id))
89
+ cluster_scope!(user,organization,scope,includes).related_clusters
17
90
  end
18
91
 
19
92
  ##
20
- # Returns a scope with filtered by clusters or
21
- # the scope filterd its organization if
22
- # the organization haven't active the cluster mode
23
- #
93
+ # Returns a scope filtered by clusters or its
94
+ # organization if the cluster mode is not active.
24
95
  #
25
96
  def cluster_scope!(user,organization,scope,includes=[])
26
- scope_klass = scope_class(scope)
27
- raise RelatedClusterEntityComplianceError, "attribute cluster_id was not found in #{scope_klass}" unless scope_klass.try(:column_names).try(:include?,'cluster_id')
28
- scope_klass = scope_klass.includes(includes) if includes.present?
29
- scope_klass = scope_klass.where(organization_id: organization)
30
-
97
+ scope_klass = scope_class(scope).where(organization_id: organization)
31
98
  session_clusters(user,organization) do |clusters|
32
- if organization.required_suborganization_mode?
33
- scope_klass = scope_klass.where("#{scope.table_name}.cluster_id IN (?)",clusters)
34
- elsif organization.optional_mode? && user.is_a_cluster_user?
35
- with_clusters = clusters.present? ? "#{scope.table_name}.cluster_id IN (#{clusters.map(&:id).join(',')})" : nil
36
- without_clusters = "#{with_clusters.blank? ? '' : ' OR ' }#{scope.table_name}.cluster_id IS NULL"
37
- scope_klass = scope_klass.where("#{with_clusters}#{without_clusters}")
99
+ if organization.is_in_cluster_mode?
100
+ scope_klass = scope_klass.select("DISTINCT ON (#{scope.table_name}.id) #{scope.table_name}.id, #{scope.table_name}.*")
101
+ scope_klass = scope_klass.includes(includes) if includes.present?
102
+ cluster_ids = clusters.map(&:id)
103
+ if organization.required_suborganization_mode?
104
+ scope_klass = scope_klass.joins(:cluster_entities).where( cluster_entities: { cluster_id: cluster_ids } )
105
+ else
106
+ or_these_cluster_ids = cluster_ids.present? ? " OR cluster_entities.cluster_id IN (#{cluster_ids.join(",")})" : ""
107
+ scope_klass = scope_klass.joins("
108
+ LEFT OUTER JOIN cluster_entities
109
+ ON entity_id = #{scope.table_name}.id
110
+ AND entity_type = '#{scope}'
111
+ ").where("cluster_entities.id IS NULL#{or_these_cluster_ids}")
112
+ end
113
+ # Provisional fix to avoid SQL clashes due to DISTINCT ON clause
114
+ scope_klass = scope_class(scope).where(organization_id: organization).where(id: scope_klass.map(&:id))
38
115
  end
39
116
  end
40
-
41
117
  scope_klass
42
118
  end
43
119
 
@@ -45,6 +121,7 @@ module Klastera
45
121
  # TODO:
46
122
  # Implement a validation to ensure that
47
123
  # object is a ActiveRecord::Base class
124
+ # (or just try to guess how to retrieve the argument class)
48
125
  #
49
126
  ##
50
127
  def scope_class(object)
@@ -59,7 +136,7 @@ module Klastera
59
136
  #
60
137
  ##
61
138
  def session_clusters(user,organization)
62
- clusters = organization.is_in_cluster_mode? ? ::ClusterUser.get_clusters_from(user,organization) : []
139
+ clusters = organization.is_in_cluster_mode? ? ::ClusterUser.clusters_from(user,organization) : []
63
140
  if block_given?
64
141
  clusters = clusters.reject{|c|c.id.blank?}
65
142
  yield(clusters)
@@ -75,7 +152,7 @@ module Klastera
75
152
  helper_method :cluster_user
76
153
  helper_method :cluster_organization
77
154
  helper_method :cluster_clusters
78
- # helper_method :cluster_clusters_ids
155
+ helper_method :cluster_scope_filtered
79
156
  helper_method :user_has_more_than_one_cluster
80
157
  helper_method :clusters_from
81
158
  end
@@ -90,8 +167,8 @@ module Klastera
90
167
  hide_action :cluster_organization=
91
168
  hide_action :cluster_clusters
92
169
  hide_action :cluster_clusters=
93
- # hide_action :cluster_clusters_ids
94
- # hide_action :cluster_clusters_ids=
170
+ hide_action :cluster_scope_filtered
171
+ hide_action :cluster_scope_filtered=
95
172
  hide_action :user_has_more_than_one_cluster
96
173
  hide_action :user_has_more_than_one_cluster=
97
174
  hide_action :clusters_from
@@ -125,9 +202,15 @@ module Klastera
125
202
  Klastera.session_clusters(cluster_user,cluster_organization)
126
203
  end
127
204
 
128
- # def cluster_clusters_ids
129
- # cluster_clusters.map(&:id)
130
- # end
205
+ def cluster_scope_filtered(scope,cluster_id,includes=[])
206
+ Klastera.cluster_scope_filtered!(
207
+ scope,
208
+ cluster_id,
209
+ cluster_user,
210
+ cluster_organization,
211
+ includes
212
+ )
213
+ end
131
214
 
132
215
  def user_has_more_than_one_cluster
133
216
  @cluster_clusters ||= cluster_clusters