klastera 1.1.6.2 → 1.2.3.2

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.
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 +3 -3
  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 +2 -2
  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: f09d153e08f0e2574fef522a3a39a8e8c81e7ccd05cccbde677a4b04c253b93f
4
- data.tar.gz: adaa84309625dc7749746d795fe8ab7c3bf7751167b58226658b7ce6f48bcd8d
3
+ metadata.gz: 5d912b888e108c33f2a258ebbe682233d943b21f83b81fb5d79295703262bef1
4
+ data.tar.gz: 3f7004752065d0a1c7f925dfc3198367e1612153e34d8dba47f558df4afbad69
5
5
  SHA512:
6
- metadata.gz: e2da72b8431f7686c68245ee06a35e77ba07912a11dbee0f2001e4fd7ee6d0a665dce5ac12526b59876b43a78f9221869a780dfae968eb6dde532c70540e58fd
7
- data.tar.gz: 90b20f2b8a742c6112344aaf67a69d9195931bec2d28d9c2ddf0ccbbf2109e6a7df1e7396f04a238f55c8e58b9deb603108327d19ea828ed31cde2ffeebfe70c
6
+ metadata.gz: 2d9da626373702d6a7453ff46d7231e5596eb1c15f4619c70e51e7f54cc1836f403b45da950dc1e686d861aa9d227dccacda106695303c75fea02edaca1fd9dc
7
+ data.tar.gz: 6d5ad5c6d6a5dcf2b13ded5181da671261c1735c19ead485c7560fc5a409de3aa6f699d7516a7b99712e34620a9c8aa940ba166d53596e70d1a9c42df3d43ff5
@@ -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,7 +20,7 @@ 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
26
  ::ClusterUser.includes(:user).where(cluster_id: organization_cluster_ids).each do |cluster_user|
@@ -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.try(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? %>
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