forest_liana 1.3.51 → 1.3.52

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
  SHA1:
3
- metadata.gz: 4fa4d0087fec1ce7d9d730640a0ec5b39035a39a
4
- data.tar.gz: d39230ec74fde4917e1532659c935b9973c6913f
3
+ metadata.gz: 49ce2bea2aeb0b45516ad7e84e4879369ea12880
4
+ data.tar.gz: 37c94be3fcd9c8ebdde55f76a10938106807a577
5
5
  SHA512:
6
- metadata.gz: 122744b37e139dfd9573f8ab12018470b4deebd5c152a4d906a8b9f77d232625373c3888daf327a6e1d84a03628de4cde8c728d98ac06c476d2ecc8bdf11c991
7
- data.tar.gz: 0388fb5e7c2baef1ac7c2110dbff673dd0915bb5393005c22775b9b4e8ebd123a0d84bdc4812479003c5f139215f51b827ebdaeee77a718297fd12eed1f9dbc0
6
+ metadata.gz: 6f867e92adf3495795418ab5fff10236b1f15e08545967a555a6582792c6f58723fd86264d4e6117bc7662e05febe32d291f51463cf40ca2f9c3e262883c3948
7
+ data.tar.gz: 7b55764e1282a53dfc3d850cd0187b266af72389d5eb1abdc447306c217cd1a39e8c0d525e4e9c7ee948b4f5a5cf9509cdcb61838f8305f9f2a2ed5a8b122b3b
@@ -13,7 +13,7 @@ module ForestLiana
13
13
  getter.perform
14
14
 
15
15
  render serializer: nil, json: serialize_models(getter.records,
16
- include: includes,
16
+ include: getter.includes,
17
17
  count: getter.count,
18
18
  params: params)
19
19
  end
@@ -65,17 +65,5 @@ module ForestLiana
65
65
  def resource_params
66
66
  ResourceDeserializer.new(@resource, params[:resource], true).perform
67
67
  end
68
-
69
- def includes
70
- @association.klass
71
- .reflect_on_all_associations
72
- .select do |a|
73
- SchemaUtils.model_included?(a.klass) &&
74
- [:belongs_to, :has_and_belongs_to_many].include?(a.macro) &&
75
- !a.options[:polymorphic]
76
- end
77
- .map {|a| a.name.to_s }
78
- end
79
-
80
68
  end
81
69
  end
@@ -16,7 +16,7 @@ module ForestLiana
16
16
  getter.perform
17
17
 
18
18
  render serializer: nil, json: serialize_models(getter.records,
19
- include: includes,
19
+ include: includes(getter),
20
20
  count: getter.count,
21
21
  params: params)
22
22
  end
@@ -26,14 +26,17 @@ module ForestLiana
26
26
  getter.perform
27
27
 
28
28
  render serializer: nil, json:
29
- serialize_model(getter.record, include: includes)
29
+ serialize_model(getter.record, include: includes(getter))
30
30
  end
31
31
 
32
32
  def create
33
33
  creator = ResourceCreator.new(@resource, params)
34
34
  creator.perform
35
35
 
36
- if creator.record.valid?
36
+ if creator.errors
37
+ render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
38
+ creator.errors), status: 400
39
+ elsif creator.record.valid?
37
40
  render serializer: nil,
38
41
  json: serialize_model(creator.record, include: includes)
39
42
  else
@@ -46,7 +49,10 @@ module ForestLiana
46
49
  updater = ResourceUpdater.new(@resource, params)
47
50
  updater.perform
48
51
 
49
- if updater.record.valid?
52
+ if updater.errors
53
+ render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
54
+ updater.errors), status: 400
55
+ elsif updater.record.valid?
50
56
  render serializer: nil,
51
57
  json: serialize_model(updater.record, include: includes)
52
58
  else
@@ -76,10 +82,8 @@ module ForestLiana
76
82
  ResourceDeserializer.new(@resource, params[:resource], true).perform
77
83
  end
78
84
 
79
- def includes
80
- SchemaUtils.one_associations(@resource)
81
- .select { |a| SchemaUtils.model_included?(a.klass) }
82
- .map { |a| a.name.to_s }
85
+ def includes(getter)
86
+ getter.includes.map(&:to_s)
83
87
  end
84
88
  end
85
89
  end
@@ -108,10 +108,14 @@ module ForestLiana
108
108
 
109
109
  if ret[:href].blank?
110
110
  begin
111
- relationship_records = object.send(attribute_name)
111
+ if @options[:include].try(:include?, attribute_name.to_s)
112
+ object.send(attribute_name)
113
+ end
112
114
 
113
- if relationship_records.respond_to?(:each)
114
- ret[:href] = "/forest/#{object.class.table_name}/#{object.id}/relationships/#{attribute_name}"
115
+ SchemaUtils.many_associations(object.class).each do |a|
116
+ if a.name == attribute_name
117
+ ret[:href] = "/forest/#{object.class.table_name}/#{object.id}/relationships/#{attribute_name}"
118
+ end
115
119
  end
116
120
  rescue TypeError, ActiveRecord::StatementInvalid, NoMethodError
117
121
  puts "Cannot load the association #{attribute_name} on #{object.class.name} #{object.id}."
@@ -186,7 +190,7 @@ module ForestLiana
186
190
  serializer.send(serializer_association(a), a.name) {
187
191
  if [:has_one, :belongs_to].include?(a.macro)
188
192
  begin
189
- object.send(a.name).try(:reload)
193
+ object.send(a.name)
190
194
  rescue ActiveRecord::RecordNotFound
191
195
  nil
192
196
  end
@@ -4,6 +4,13 @@ module ForestLiana
4
4
  @resource = resource
5
5
  @association = association
6
6
  @params = params
7
+ @field_names_requested = field_names_requested
8
+ end
9
+
10
+ def field_names_requested
11
+ return nil unless @params[:fields] && @params[:fields][@association.table_name]
12
+ @params[:fields][@association.table_name].split(',')
13
+ .map { |name| name.to_sym }
7
14
  end
8
15
 
9
16
  def perform
@@ -11,6 +18,8 @@ module ForestLiana
11
18
  .unscoped
12
19
  .find(@params[:id])
13
20
  .send(@params[:association_name])
21
+ .select(select)
22
+ .eager_load(includes)
14
23
  @records = sort_query
15
24
  end
16
25
 
@@ -18,12 +27,38 @@ module ForestLiana
18
27
  @records.limit(limit).offset(offset)
19
28
  end
20
29
 
30
+ def includes
31
+ @association.klass
32
+ .reflect_on_all_associations
33
+ .select do |association|
34
+ inclusion = SchemaUtils.model_included?(association.klass) &&
35
+ [:belongs_to, :has_and_belongs_to_many].include?(association.macro) &&
36
+ !association.options[:polymorphic]
37
+
38
+ if @field_names_requested
39
+ inclusion && @field_names_requested.include?(association.name)
40
+ else
41
+ inclusion
42
+ end
43
+ end
44
+ .map { |association| association.name.to_s }
45
+ end
46
+
21
47
  def count
22
48
  @records.to_a.length
23
49
  end
24
50
 
25
51
  private
26
52
 
53
+ def select
54
+ column_names = @association.klass.column_names.map { |name| name.to_sym }
55
+ if @field_names_requested
56
+ column_names & @field_names_requested
57
+ else
58
+ column_names
59
+ end
60
+ end
61
+
27
62
  def association_table_name
28
63
  @resource.reflect_on_association(@params[:association_name])
29
64
  .try(:table_name)
@@ -1,19 +1,26 @@
1
1
  module ForestLiana
2
2
  class ResourceCreator
3
3
  attr_accessor :record
4
+ attr_accessor :errors
4
5
 
5
6
  def initialize(resource, params)
6
7
  @resource = resource
7
8
  @params = params
9
+ @errors = nil
8
10
  end
9
11
 
10
12
  def perform
11
- if has_strong_parameter
12
- @record = @resource.create(resource_params)
13
- else
14
- @record = @resource.create(resource_params, without_protection: true)
13
+ begin
14
+ if has_strong_parameter
15
+ @record = @resource.create(resource_params)
16
+ else
17
+ @record = @resource.create(resource_params, without_protection: true)
18
+ end
19
+ set_has_many_relationships
20
+ rescue ActiveRecord::StatementInvalid => exception
21
+ # NOTICE: SQL request cannot be executed properly
22
+ @errors = [{ detail: exception.cause.error }]
15
23
  end
16
- set_has_many_relationships
17
24
  end
18
25
 
19
26
  def resource_params
@@ -8,7 +8,13 @@ module ForestLiana
8
8
  end
9
9
 
10
10
  def perform
11
- @record = @resource.find(@params[:id])
11
+ @record = @resource.eager_load(includes).find(@params[:id])
12
+ end
13
+
14
+ def includes
15
+ SchemaUtils.one_associations(@resource)
16
+ .select { |association| SchemaUtils.model_included?(association.klass) }
17
+ .map(&:name)
12
18
  end
13
19
 
14
20
  end
@@ -1,19 +1,26 @@
1
1
  module ForestLiana
2
2
  class ResourceUpdater
3
3
  attr_accessor :record
4
+ attr_accessor :errors
4
5
 
5
6
  def initialize(resource, params)
6
7
  @resource = resource
7
8
  @params = params
9
+ @errors = nil
8
10
  end
9
11
 
10
12
  def perform
11
- @record = @resource.find(@params[:id])
13
+ begin
14
+ @record = @resource.find(@params[:id])
12
15
 
13
- if has_strong_parameter
14
- @record.update_attributes(resource_params)
15
- else
16
- @record.update_attributes(resource_params, without_protection: true)
16
+ if has_strong_parameter
17
+ @record.update_attributes(resource_params)
18
+ else
19
+ @record.update_attributes(resource_params, without_protection: true)
20
+ end
21
+ rescue ActiveRecord::StatementInvalid => exception
22
+ # NOTICE: SQL request cannot be executed properly
23
+ @errors = [{ detail: exception.cause.error }]
17
24
  end
18
25
  end
19
26
 
@@ -3,6 +3,30 @@ module ForestLiana
3
3
  def initialize(resource, params)
4
4
  @resource = resource
5
5
  @params = params
6
+ @field_names_requested = field_names_requested
7
+ end
8
+
9
+ def field_names_requested
10
+ return nil unless @params[:fields] && @params[:fields][@resource.table_name]
11
+
12
+ associations_for_query = []
13
+
14
+ # NOTICE: Populate the necessary associations for filters
15
+ if @params[:filter]
16
+ @params[:filter].each do |field, values|
17
+ if field.include? ':'
18
+ associations_for_query << field.split(':').first.to_sym
19
+ end
20
+ end
21
+ end
22
+
23
+ if @params[:sort] && @params[:sort].include?('.')
24
+ associations_for_query << @params[:sort].split('.').first.to_sym
25
+ end
26
+
27
+ field_names = @params[:fields][@resource.table_name].split(',')
28
+ .map { |name| name.to_sym }
29
+ field_names | associations_for_query
6
30
  end
7
31
 
8
32
  def perform
@@ -12,17 +36,29 @@ module ForestLiana
12
36
  end
13
37
 
14
38
  def records
15
- @sorted_records.offset(offset).limit(limit).to_a
39
+ @sorted_records.select(select).offset(offset).limit(limit).to_a
16
40
  end
17
41
 
18
42
  def count
19
43
  @records.count
20
44
  end
21
45
 
46
+ def includes
47
+ includes = SchemaUtils.one_associations(@resource)
48
+ .select { |association| SchemaUtils.model_included?(association.klass) }
49
+ .map(&:name)
50
+
51
+ if @field_names_requested
52
+ includes & @field_names_requested
53
+ else
54
+ includes
55
+ end
56
+ end
57
+
22
58
  private
23
59
 
24
60
  def search_query
25
- SearchQueryBuilder.new(@records, @params).perform
61
+ SearchQueryBuilder.new(@records, @params, includes).perform
26
62
  end
27
63
 
28
64
  def sort_query
@@ -31,9 +67,6 @@ module ForestLiana
31
67
  order = detect_sort_order(@params[:sort])
32
68
  field.slice!(0) if order == :desc
33
69
 
34
- ref = field.split('.')[0]
35
- @records = @records.includes(ref) if association?(ref)
36
-
37
70
  field = detect_reference(field)
38
71
  if field.index('.').nil?
39
72
  @records = @records
@@ -63,7 +96,7 @@ module ForestLiana
63
96
  .find {|a| a.name == ref.to_sym }
64
97
 
65
98
  if association
66
- "#{association.table_name}.#{field}"
99
+ "\"#{association.table_name}\".\"#{field}\""
67
100
  else
68
101
  param
69
102
  end
@@ -76,10 +109,13 @@ module ForestLiana
76
109
  @resource.reflect_on_association(field.to_sym).present?
77
110
  end
78
111
 
79
- def includes
80
- SchemaUtils.one_associations(@resource)
81
- .select { |a| SchemaUtils.model_included?(a.klass) }
82
- .map(&:name)
112
+ def select
113
+ column_names = @resource.column_names.map { |name| name.to_sym }
114
+ if @field_names_requested
115
+ column_names & @field_names_requested
116
+ else
117
+ column_names
118
+ end
83
119
  end
84
120
 
85
121
  def offset
@@ -13,6 +13,12 @@ module ForestLiana
13
13
  end
14
14
  end
15
15
 
16
+ def self.many_associations(active_record_class)
17
+ self.associations(active_record_class).select do |x|
18
+ [:has_many, :has_and_belongs_to_many].include?(x.macro)
19
+ end
20
+ end
21
+
16
22
  def self.find_model_from_table_name(table_name)
17
23
  model = nil
18
24
 
@@ -66,4 +72,3 @@ module ForestLiana
66
72
  end
67
73
  end
68
74
  end
69
-
@@ -1,9 +1,10 @@
1
1
  module ForestLiana
2
2
  class SearchQueryBuilder
3
3
 
4
- def initialize(resource, params)
4
+ def initialize(resource, params, includes)
5
5
  @resource = @records = resource
6
6
  @params = params
7
+ @includes = includes
7
8
  end
8
9
 
9
10
  def perform
@@ -51,15 +52,16 @@ module ForestLiana
51
52
  end
52
53
 
53
54
  SchemaUtils.one_associations(@resource).map(&:name).each do |association|
54
- resource = @resource.reflect_on_association(association.to_sym)
55
- resource.klass.columns.each do |column|
56
- if !column.array && (column.type == :string || column.type == :text)
57
- conditions <<
58
- "LOWER(\"#{resource.table_name}\".\"#{column.name}\") LIKE " +
59
- "'%#{@params[:search].downcase}%'"
55
+ if @includes.include? association.to_sym
56
+ resource = @resource.reflect_on_association(association.to_sym)
57
+ resource.klass.columns.each do |column|
58
+ if !column.array && (column.type == :string || column.type == :text)
59
+ conditions <<
60
+ "LOWER(\"#{resource.table_name}\".\"#{column.name}\") LIKE " +
61
+ "'%#{@params[:search].downcase}%'"
62
+ end
60
63
  end
61
64
  end
62
- @resource = @resource.eager_load(association.to_sym)
63
65
  end
64
66
 
65
67
  @records = @resource.where(conditions.join(' OR '))
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "1.3.51"
2
+ VERSION = "1.3.52"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_liana
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.51
4
+ version: 1.3.52
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Munda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-01 00:00:00.000000000 Z
11
+ date: 2016-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails