forest_admin_datasource_active_record 1.0.0.pre.beta.53 → 1.0.0.pre.beta.55

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 241691e966a9bd75b1cf66d07cc640e8ad2201fef29640568fafca6490c28250
4
- data.tar.gz: 4db07ffe9fa5d0c0f9397c9b4b7073850440aa5a68d8329ef1e350d2e23ba7db
3
+ metadata.gz: 24b6a78fb3119d0686735b3d7d550148fad3d6a8c6a0251867230f13cc0c043f
4
+ data.tar.gz: 2912d1b2435e29fd19a3284debaa7ba97bdcd1bd223af8629645b9630a915656
5
5
  SHA512:
6
- metadata.gz: d7b4af902acab6b8edd4067603f6de7f1e3420608a78b44a5ee339125030b54e4508a50f4956c50bad891a8d77c92f6854d922fd5e3debfbe9cf6706555fcacf
7
- data.tar.gz: 817416e1dc2c846b473f1afec82f922205560c8802f8b340507337714aa4388bc1d328436ad2b5bfaae24cef2b52960da69d6c25e7cb5c4b991a17bfd1e52d3c
6
+ metadata.gz: ec1c79b449b3855576a9a318b50094fff0cb126a8a421718175b68bb76bf83939badc2a3c68625f3c723a53e0051d7f8d36621bfd5f618b6f7307e49a7553aba
7
+ data.tar.gz: d059a3bb21bc5b66a5bfceeb13f6e3b12abe5690a5cb9f6dfe26c80c5acdcbd4d53cf97476e69ac260a1762851a2d23a04d0dcfbeb8fe70a2d754c228f891e37
@@ -47,11 +47,10 @@ module ForestAdminDatasourceActiveRecord
47
47
 
48
48
  def fetch_fields
49
49
  @model.columns_hash.each do |column_name, column|
50
- # TODO: check is not sti column
51
50
  field = ForestAdminDatasourceToolkit::Schema::ColumnSchema.new(
52
51
  column_type: get_column_type(@model, column),
53
52
  filter_operators: operators_for_column_type(get_column_type(@model, column)),
54
- is_primary_key: column_name == @model.primary_key,
53
+ is_primary_key: column_name == @model.primary_key || @model.primary_key.include?(column_name),
55
54
  is_read_only: false,
56
55
  is_sortable: true,
57
56
  default_value: column.default,
@@ -5,6 +5,7 @@ module ForestAdminDatasourceActiveRecord
5
5
  def initialize(db_config = {})
6
6
  super()
7
7
  @models = []
8
+ @habtm_models = {}
8
9
  init_orm(db_config)
9
10
  generate
10
11
  end
@@ -19,11 +20,52 @@ module ForestAdminDatasourceActiveRecord
19
20
  end
20
21
 
21
22
  def fetch_model(model)
22
- @models << model unless model.abstract_class? || @models.include?(model) || !model.table_exists?
23
+ if model.name.start_with?('HABTM_')
24
+ build_habtm(model)
25
+ else
26
+ @models << model unless model.abstract_class? || @models.include?(model) || !model.table_exists?
27
+ end
23
28
  end
24
29
 
25
30
  def init_orm(db_config)
26
31
  ActiveRecord::Base.establish_connection(db_config)
27
32
  end
33
+
34
+ def build_habtm(model)
35
+ if @habtm_models.key?(model.table_name)
36
+ @habtm_models[model.table_name].left_reflection = model.right_reflection
37
+ # when the second model is added, we can push the HABTM model to the models list
38
+ @models << make_through_model(
39
+ model.table_name,
40
+ [
41
+ @habtm_models[model.table_name].left_reflection,
42
+ @habtm_models[model.table_name].right_reflection
43
+ ]
44
+ )
45
+ else
46
+ @habtm_models[model.table_name] = model
47
+ end
48
+ end
49
+
50
+ def make_through_model(table_name, associations)
51
+ through_model = Class.new(ActiveRecord::Base) do
52
+ class << self
53
+ attr_accessor :name, :table_name
54
+ end
55
+
56
+ def self.add_association(name, options)
57
+ belongs_to name, required: false, **options
58
+ end
59
+ end
60
+
61
+ through_model.name = table_name.singularize
62
+ through_model.table_name = table_name
63
+ through_model.primary_key = [associations[0].foreign_key, associations[1].foreign_key]
64
+ associations.each do |association|
65
+ through_model.add_association(association.name, association.options)
66
+ end
67
+
68
+ through_model
69
+ end
28
70
  end
29
71
  end
@@ -50,39 +50,41 @@ module ForestAdminDatasourceActiveRecord
50
50
 
51
51
  def apply_condition_tree(condition_tree, aggregator = nil)
52
52
  if condition_tree.is_a? Nodes::ConditionTreeBranch
53
- aggregator = condition_tree.aggregator.downcase
53
+ aggregator = condition_tree.aggregator.downcase.to_sym
54
54
  condition_tree.conditions.each do |condition|
55
- query = apply_condition_tree(condition, aggregator)
56
- @query = @query.send(aggregator, query)
55
+ @query = apply_condition_tree(condition, aggregator)
56
+ @query = @query.send(aggregator, @query)
57
57
  end
58
58
 
59
59
  @query
60
60
  else
61
- compute_main_operator(condition_tree, aggregator || 'and')
61
+ @query = compute_main_operator(condition_tree, aggregator || :and)
62
62
  end
63
63
  end
64
64
 
65
65
  def compute_main_operator(condition_tree, aggregator)
66
66
  field = format_field(condition_tree.field)
67
67
  value = condition_tree.value
68
+ aggregator = aggregator.to_sym
68
69
 
69
70
  case condition_tree.operator
70
71
  when Operators::PRESENT
71
- @query = @query.send(aggregator, @query.where.not({ field => nil }))
72
+ @query = query_aggregator(aggregator, @collection.model.where.not({ field => nil }))
72
73
  when Operators::EQUAL, Operators::IN
73
- @query = @query.send(aggregator, @query.where({ field => value }))
74
+ @query = query_aggregator(aggregator, @collection.model.where({ field => value }))
74
75
  when Operators::NOT_EQUAL, Operators::NOT_IN
75
- @query = @query.send(aggregator, @query.where.not({ field => value }))
76
+ @query = query_aggregator(aggregator, @collection.model.where.not({ field => value }))
76
77
  when Operators::GREATER_THAN
77
- @query = @query.send(aggregator, @query.where(@arel_table[field.to_sym].gt(value)))
78
+ @query = query_aggregator(aggregator, @collection.model.where(@arel_table[field.to_sym].gt(value)))
78
79
  when Operators::LESS_THAN
79
- @query = @query.send(aggregator, @query.where(@arel_table[field.to_sym].lt(value)))
80
+ @query = query_aggregator(aggregator, @collection.model.where(@arel_table[field.to_sym].lt(value)))
80
81
  when Operators::NOT_CONTAINS
81
- @query = @query.send(aggregator, @query.where.not(@arel_table[field.to_sym].matches("%#{value}%")))
82
+ @query = query_aggregator(aggregator,
83
+ @collection.model.where.not(@arel_table[field.to_sym].matches("%#{value}%")))
82
84
  when Operators::LIKE
83
- @query = @query.send(aggregator, @query.where(@arel_table[field.to_sym].matches(value)))
85
+ @query = query_aggregator(aggregator, @collection.model.where(@arel_table[field.to_sym].matches(value)))
84
86
  when Operators::INCLUDES_ALL
85
- @query = @query.send(aggregator, @query.where(@arel_table[field.to_sym].matches_all(value)))
87
+ @query = query_aggregator(aggregator, @collection.model.where(@arel_table[field.to_sym].matches_all(value)))
86
88
  end
87
89
 
88
90
  @query
@@ -93,7 +95,7 @@ module ForestAdminDatasourceActiveRecord
93
95
  @select += @projection.columns.map { |field| "#{@collection.model.table_name}.#{field}" }
94
96
  @projection.relations.each_key do |relation|
95
97
  relation_schema = @collection.schema[:fields][relation]
96
- @select << if relation_schema.type == 'OneToOne'
98
+ @select << if relation_schema.type == 'OneToOne' || relation_schema.type == 'PolymorphicOneToOne'
97
99
  "#{@collection.model.table_name}.#{relation_schema.origin_key_target}"
98
100
  else
99
101
  "#{@collection.model.table_name}.#{relation_schema.foreign_key}"
@@ -107,35 +109,41 @@ module ForestAdminDatasourceActiveRecord
107
109
  def apply_select
108
110
  unless @projection.nil?
109
111
  @query = @query.select(@select.join(', '))
110
- @query = @query.eager_load(@projection.relations.keys.map(&:to_sym))
111
- # TODO: replace eager_load by joins because eager_load select ALL columns of relation
112
- # @query = @query.joins(@projection.relations.keys.map(&:to_sym))
112
+ @query = @query.includes(@projection.relations.keys.map(&:to_sym))
113
113
  end
114
114
 
115
115
  @query
116
116
  end
117
117
 
118
- def add_join_relation(relation, relation_name)
119
- if relation.type == 'ManyToMany'
120
- # TODO: to implement
121
- else
122
- @query = @query.joins(relation_name.to_sym)
123
- end
118
+ def add_join_relation(relation_name)
119
+ @query = @query.includes(relation_name.to_sym)
124
120
 
125
121
  @query
126
122
  end
127
123
 
128
124
  def format_field(field)
125
+ @select << "#{@collection.model.table_name}.#{field}"
126
+
129
127
  if field.include?(':')
130
128
  relation_name, field = field.split(':')
131
129
  relation = @collection.schema[:fields][relation_name]
132
130
  table_name = @collection.datasource.get_collection(relation.foreign_collection).model.table_name
133
- add_join_relation(relation, relation_name)
131
+ add_join_relation(relation_name)
132
+ @select << "#{table_name}.#{field}"
133
+
134
134
  return "#{table_name}.#{field}"
135
135
  end
136
136
 
137
137
  field
138
138
  end
139
+
140
+ def query_aggregator(aggregator, query)
141
+ if !@query.respond_to?(:where_clause) || @query.where_clause.empty?
142
+ query
143
+ else
144
+ @query.send(aggregator, query)
145
+ end
146
+ end
139
147
  end
140
148
  end
141
149
  end
@@ -1,3 +1,3 @@
1
1
  module ForestAdminDatasourceActiveRecord
2
- VERSION = "1.0.0-beta.53"
2
+ VERSION = "1.0.0-beta.55"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_admin_datasource_active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.beta.53
4
+ version: 1.0.0.pre.beta.55
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthieu
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-06-10 00:00:00.000000000 Z
12
+ date: 2024-06-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord