klastera 1.5.5 → 1.5.5.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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +0 -0
  3. data/README.rdoc +0 -0
  4. data/Rakefile +0 -0
  5. data/app/assets/javascripts/klastera/application.js +0 -0
  6. data/app/assets/javascripts/klastera/clusters.js +0 -0
  7. data/app/assets/stylesheets/klastera/clusters.scss +0 -0
  8. data/app/controllers/klastera/application_controller.rb +0 -0
  9. data/app/controllers/klastera/clusters_controller.rb +0 -0
  10. data/app/helpers/klastera/application_helper.rb +0 -0
  11. data/app/models/klastera/cluster.rb +0 -0
  12. data/app/models/klastera/cluster_entity.rb +0 -0
  13. data/app/models/klastera/cluster_filter.rb +0 -0
  14. data/app/models/klastera/cluster_user.rb +0 -0
  15. data/app/models/klastera/concerns/cluster.rb +0 -0
  16. data/app/models/klastera/concerns/cluster_entity.rb +0 -0
  17. data/app/models/klastera/concerns/cluster_filter.rb +0 -0
  18. data/app/models/klastera/concerns/cluster_user.rb +0 -0
  19. data/app/models/klastera/concerns/clusterizable.rb +8 -4
  20. data/app/models/klastera/concerns/organization.rb +0 -0
  21. data/app/models/klastera/concerns/transfer.rb +0 -0
  22. data/app/models/klastera/concerns/user.rb +0 -0
  23. data/app/models/klastera/transfer.rb +0 -0
  24. data/app/views/klastera/clusters/_filter.html.erb +0 -0
  25. data/app/views/klastera/clusters/_form.html.erb +0 -0
  26. data/app/views/klastera/clusters/_form_transfer.html.erb +0 -0
  27. data/app/views/klastera/clusters/_table.html.erb +0 -0
  28. data/app/views/klastera/clusters/create.js.erb +0 -0
  29. data/app/views/klastera/clusters/destroy.js.erb +0 -0
  30. data/app/views/klastera/clusters/edit.html.erb +0 -0
  31. data/app/views/klastera/clusters/index.html.erb +0 -0
  32. data/app/views/klastera/clusters/new.html.erb +0 -0
  33. data/app/views/klastera/clusters/transfer.html.erb +0 -0
  34. data/app/views/klastera/clusters/update.js.erb +0 -0
  35. data/app/views/layouts/klastera/_cluster_entity_fields.html.erb +0 -0
  36. data/app/views/layouts/klastera/_cluster_filter.html.erb +0 -0
  37. data/app/views/layouts/klastera/_cluster_role.html.erb +0 -0
  38. data/app/views/layouts/klastera/_cluster_selector.html.erb +0 -0
  39. data/app/views/layouts/klastera/_cluster_user_fields.html.erb +0 -0
  40. data/app/views/layouts/klastera/_nested_cluster_entity.html.erb +0 -0
  41. data/app/views/layouts/klastera/_nested_cluster_user.html.erb +0 -0
  42. data/app/views/layouts/klastera/_options.html.erb +0 -0
  43. data/config/locales/es.yml +0 -0
  44. data/config/routes.rb +0 -0
  45. data/db/migrate/20200324203929_create_klastera_clusters.rb +0 -0
  46. data/db/migrate/20200326111219_add_cluster_options_to_organizations.rb +0 -0
  47. data/db/migrate/20200330010551_create_klastera_cluster_users.rb +0 -0
  48. data/db/migrate/20200330221601_add_order_field_to_clusters.rb +0 -0
  49. data/db/migrate/20200518142609_create_klastera_cluster_entities.rb +0 -0
  50. data/db/migrate/20200908180057_add_cluster_config_to_organization.rb +0 -0
  51. data/db/migrate/20220602222332_add_unique_index_to_cluster_entities.rb +0 -0
  52. data/lib/klastera/engine.rb +0 -0
  53. data/lib/klastera/version.rb +1 -1
  54. data/lib/klastera.rb +24 -8
  55. data/lib/tasks/klastera_tasks.rake +0 -0
  56. data/test/controllers/klastera/clusters_controller_test.rb +0 -0
  57. data/test/fixtures/klastera/cluster_users.yml +0 -0
  58. data/test/fixtures/klastera/clusters.yml +0 -0
  59. data/test/integration/navigation_test.rb +0 -0
  60. data/test/klastera_test.rb +0 -0
  61. data/test/models/klastera/cluster_test.rb +0 -0
  62. data/test/models/klastera/cluster_user_test.rb +0 -0
  63. data/test/models/klastera/clusterizable_nested_attributes_test.rb +43 -0
  64. data/test/test_helper.rb +0 -0
  65. metadata +10 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f9a474c54506a3e2a3b92ce5961de94a71dd28699354b671be08337b4bdfac5
4
- data.tar.gz: 01db2dd1040338587462593e22ef1103f3c7ecd6ce13e48656dcd47eb7cf31c9
3
+ metadata.gz: 7f593dccae852483eb2b18e8254ee94c1e44804bcb59780cd26a8987ef383443
4
+ data.tar.gz: f28976b48568045dfe38b3feb2915de5e87b079279b0a31e481f48741fdbd0a0
5
5
  SHA512:
6
- metadata.gz: a54cf22f075c58094950f74345fe924686f79ab8454ca6afc4b80555bbe26367d56500867b1fbf83f3f270d9f0effe9d9907ceacdbc18f02f32f35654abf237d
7
- data.tar.gz: d197f19bc4c590359364cbd965295fb981dedfc22f0e33cf02673c75bfc5228b50f6543d316ee2de887437deec92ceb65bcadc617f1d6a4b1af3f2e44f53ae05
6
+ metadata.gz: a2b1d549df310a5bf569316f5e9de36f66c9be7b5d052108d85aa1345f6d05527a536494ca39ea37e2f19f663e8973dd5d62a107ea101168f63d5a2ace6566b4
7
+ data.tar.gz: 1353ffb7147a62d4e35cf28a0ccafa2e976460e96db0dc566cc48ed1db0e16e2ea315d65fcd8b12c2642cea76f53e3a2b2a8c10d48000f08efb93f72f4f9c749
data/MIT-LICENSE CHANGED
File without changes
data/README.rdoc CHANGED
File without changes
data/Rakefile CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -7,7 +7,11 @@ module Klastera::Concerns::Clusterizable
7
7
  belongs_to :cluster
8
8
 
9
9
  has_many :cluster_entities, as: :entity, class_name: "Klastera::ClusterEntity"
10
- accepts_nested_attributes_for :cluster_entities, reject_if: :all_blank, allow_destroy: true
10
+ # reject_if exige cluster_id presente. Con :all_blank, una fila EXISTENTE (con id) cuyo select
11
+ # se deja en blanco (include_blank del formulario) no se descarta y se guarda con cluster_id=NULL:
12
+ # queda un cluster_entity huérfano, invisible en el formulario, que cuenta en las validaciones y
13
+ # bloquea el guardado. Para quitar una zona existente se usa _destroy, no vaciar el select.
14
+ accepts_nested_attributes_for :cluster_entities, reject_if: ->(attrs) { attrs[:cluster_id].blank? }, allow_destroy: true
11
15
 
12
16
  validates :cluster_id, presence: true, if: -> { cluster_id.present? && organization.present? && organization.required_suborganization_mode? }
13
17
  validate :at_least_one_cluster_entity, if: -> { organization.present? && organization.required_suborganization_mode? }
@@ -33,7 +37,7 @@ module Klastera::Concerns::Clusterizable
33
37
  def clusters_string_separated_by(separator, attribute=:name)
34
38
  # Use Rails cache for frequently accessed cluster strings
35
39
  cache_key = [self.cache_key_with_version, :clusters_string, separator, attribute]
36
-
40
+
37
41
  Rails.cache.fetch(cache_key, expires_in: 30.minutes) do
38
42
  Klastera.entity_clusters_string_list!(
39
43
  cluster_entities, separator, attribute
@@ -74,9 +78,9 @@ module Klastera::Concerns::Clusterizable
74
78
  ##
75
79
  def preload_clusters(collection)
76
80
  return collection if collection.empty?
77
-
81
+
78
82
  ActiveRecord::Associations::Preloader.new.preload(
79
- collection,
83
+ collection,
80
84
  cluster_entities: :cluster
81
85
  )
82
86
  collection
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data/config/routes.rb CHANGED
File without changes
File without changes
@@ -1,3 +1,3 @@
1
1
  module Klastera
2
- VERSION = "1.5.5"
2
+ VERSION = "1.5.5.2"
3
3
  end
data/lib/klastera.rb CHANGED
@@ -53,10 +53,10 @@ module Klastera
53
53
  if allowed_cluster_ids.is_a?(Array)
54
54
  _cluster_entities.select!{|ce| allowed_cluster_ids.include?(ce.cluster_id)}
55
55
  end
56
-
56
+
57
57
  # Performance optimization: Use preloaded data when available
58
58
  if cluster_entities.respond_to?(:loaded?) && cluster_entities.loaded? &&
59
- _cluster_entities.all? { |ce| ce.association(:cluster).loaded? }
59
+ _cluster_entities.all? { |ce| ce.association(:cluster).loaded? }
60
60
  # Use in-memory data (much faster)
61
61
  _cluster_entities.map do |ce|
62
62
  ce.cluster.try(attribute)
@@ -64,13 +64,29 @@ module Klastera
64
64
  else
65
65
  # Fallback to original method with database query
66
66
  # But use a single query instead of N+1
67
- cluster_ids = _cluster_entities.map(&:cluster_id).compact.uniq
67
+
68
+ cluster_ids = _cluster_entities.filter_map(&:cluster_id).uniq
68
69
  return "" if cluster_ids.empty?
69
-
70
- clusters_hash = ::Cluster.where(id: cluster_ids).pluck(:id, attribute).to_h
71
- _cluster_entities.map do |ce|
72
- clusters_hash[ce.cluster_id]
73
- end.compact.sort.join(separator)
70
+
71
+ records = ::Cluster.where(id: cluster_ids).pluck(:id, attribute)
72
+ return "" if records.empty?
73
+
74
+ # clusters_hash = if records.any? && !records.first.is_a?(Array)
75
+ # records.map { |id| [id, id] }.to_h
76
+ # else
77
+ # records.to_h
78
+ # end
79
+ # _cluster_entities.map do |ce|
80
+ # clusters_hash[ce.cluster_id]
81
+ # end.compact.sort.join(separator)
82
+
83
+ clusters_hash = records.first.is_a?(Array) ? records.to_h : records.index_by(&:itself)
84
+ _cluster_entities
85
+ .filter_map { |entity| clusters_hash[entity.cluster_id] }
86
+ .uniq
87
+ .sort
88
+ .join(separator)
89
+
74
90
  end
75
91
  end
76
92
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ # Estos tests no corren dentro de este repo: no existe test/dummy y usan modelos de Llegando
4
+ # (Profile, Organization, ::Cluster). Para correrlos hay que copiarlos a llegando-neo con la gema
5
+ # apuntando a esta rama.
6
+ #
7
+ # El test que prueba el fix es "no vacia el cluster_id de una fila existente": con :all_blank
8
+ # falla (la fila queda con cluster_id NULL). Los otros dos pasan igual en main y protegen que
9
+ # el cambio no rompa el descarte de filas nuevas vacias ni agregar/destruir zonas.
10
+ module Klastera
11
+ class ClusterizableNestedAttributesTest < ActiveSupport::TestCase
12
+ def build_entity_with_cluster
13
+ entity = Profile.create!(organization: Organization.first, nid: SecureRandom.hex(4))
14
+ cluster = ::Cluster.create!(organization: entity.organization, name: "c-#{SecureRandom.hex(2)}")
15
+ ce = Klastera::ClusterEntity.create!(entity: entity, cluster_id: cluster.id)
16
+ [entity.reload, ce, cluster]
17
+ end
18
+
19
+ test "descarta una fila nueva con cluster_id vacio" do
20
+ entity, = build_entity_with_cluster
21
+ entity.assign_attributes(cluster_entities_attributes: { "0" => { "cluster_id" => "", "_destroy" => "false" } })
22
+ assert_equal 1, entity.cluster_entities.size
23
+ end
24
+
25
+ test "no vacia el cluster_id de una fila existente" do
26
+ entity, ce, cluster = build_entity_with_cluster
27
+ entity.assign_attributes(cluster_entities_attributes: { "0" => { "id" => ce.id, "cluster_id" => "", "_destroy" => "false" } })
28
+ entity.save!
29
+ assert_equal cluster.id, ce.reload.cluster_id
30
+ end
31
+
32
+ test "sigue permitiendo agregar y destruir zonas" do
33
+ entity, ce, = build_entity_with_cluster
34
+ otro = ::Cluster.create!(organization: entity.organization, name: "otro")
35
+ entity.assign_attributes(cluster_entities_attributes: {
36
+ "0" => { "id" => ce.id, "_destroy" => "1" },
37
+ "1" => { "cluster_id" => otro.id.to_s, "_destroy" => "false" }
38
+ })
39
+ assert entity.cluster_entities.any?(&:marked_for_destruction?)
40
+ assert entity.cluster_entities.any? { |c| c.new_record? && c.cluster_id == otro.id }
41
+ end
42
+ end
43
+ end
data/test/test_helper.rb CHANGED
File without changes
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.5.5
4
+ version: 1.5.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gino Barahona
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-20 00:00:00.000000000 Z
11
+ date: 2026-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -108,6 +108,7 @@ files:
108
108
  - test/klastera_test.rb
109
109
  - test/models/klastera/cluster_test.rb
110
110
  - test/models/klastera/cluster_user_test.rb
111
+ - test/models/klastera/clusterizable_nested_attributes_test.rb
111
112
  - test/test_helper.rb
112
113
  homepage: https://github.com/ginosx/klastera
113
114
  licenses:
@@ -128,16 +129,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  - !ruby/object:Gem::Version
129
130
  version: '0'
130
131
  requirements: []
131
- rubygems_version: 3.4.10
132
+ rubygems_version: 3.1.6
132
133
  signing_key:
133
134
  specification_version: 4
134
135
  summary: Clusterization Engine
135
136
  test_files:
136
- - test/controllers/klastera/clusters_controller_test.rb
137
- - test/fixtures/klastera/cluster_users.yml
138
- - test/fixtures/klastera/clusters.yml
139
137
  - test/integration/navigation_test.rb
140
- - test/klastera_test.rb
141
- - test/models/klastera/cluster_test.rb
138
+ - test/models/klastera/clusterizable_nested_attributes_test.rb
142
139
  - test/models/klastera/cluster_user_test.rb
140
+ - test/models/klastera/cluster_test.rb
141
+ - test/klastera_test.rb
142
+ - test/fixtures/klastera/clusters.yml
143
+ - test/fixtures/klastera/cluster_users.yml
143
144
  - test/test_helper.rb
145
+ - test/controllers/klastera/clusters_controller_test.rb