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

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: 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