rexport 1.3.0 → 1.4.0

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: 91b93bfa7c3dea7a0a9df8dce1e59681aa8de412825556ad9c8b1c743d08c29b
4
- data.tar.gz: ac601552d8d3b65b106bab210dc142eda8d88fc489742021100364f1dfc0707b
3
+ metadata.gz: 645738a1ea2afb2feee13d71a5c4e5e01ce10fe6e872f1bb5f01077e6db05638
4
+ data.tar.gz: 37c36f6d85dd9a877e8e8de45642c3e8536aab04c71ea1aeb231abf750ed24f5
5
5
  SHA512:
6
- metadata.gz: 85cb6d95f199755c44ade632a1cedbe3c6c8834a9d9da9ea1938d1749ee3a4f7045b4fa5ccc091245c0c6471cf24a0d435964621fc93f4f7ab431e4eb8bf2a01
7
- data.tar.gz: e69b135131c1484152e10cfc4e0b580888b308084c06b050962dd690dc6917e730be489dedb88265e218ea11ca75635e6d375f89b5c77de84f7800985f901c49
6
+ metadata.gz: 9f9b3fcc9a4823a79ea2341aa22d918acd1fbad669d6eae62fec6fcc386923f49616d977745bfd81a179b92c3b9fdc65b058c53bf8cb1d9f4cfe6e66e9f41546
7
+ data.tar.gz: 19f28b327e48fcf962f17bd91c3100dd6bd912872ed822d6cb8ce2224ca4985d36d448a5af0895dcc0bceef803fd1719310deab6e402af2e9d87415adfa25f12
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/setup"
2
4
 
3
5
  require "bundler/gem_tasks"
@@ -1,28 +1,50 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ExportsHelper
4
+ BOOLEAN_OPTIONS = [nil, ["true", 1], ["false", 0]].freeze
5
+ FORM_TAG_CLASS = "form-control"
6
+
2
7
  def filter_value_field(rexport_model, field)
8
+ ActiveSupport::Deprecation.warn(
9
+ "Calling #filter_value_field is deprecated. Use #rexport_filter_form_tag instead"
10
+ )
11
+ rexport_filter_tag(@export, rexport_model, field) # rubocop:disable Rails/HelperInstanceVariable
12
+ end
13
+
14
+ def rexport_filter_tag(export, rexport_model, field) # rubocop:disable Metrics/MethodLength
3
15
  filter_field = rexport_model.field_path(rexport_model.filter_column(field))
4
- tag_name = "export[export_filter_attributes][#{filter_field.to_s}]"
5
- value = @export.filter_value(filter_field)
16
+ tag_name = "export[export_filter_attributes][#{filter_field}]"
17
+ value = export.filter_value(filter_field)
6
18
 
7
19
  case field.type
8
- when :boolean
9
- select_tag(tag_name, options_for_select([nil, ['true', 1], ['false', 0]], (value.to_i unless value.nil?)), class: 'form-control')
10
20
  when :association
11
- association, text_method = field.method.split('.')
12
- select_tag(tag_name,
13
- ('<option value=""></option>' +
14
- options_from_collection_for_select(
21
+ association, text_method = field.method.split(".")
22
+ association_filter_select_tag(
23
+ tag_name,
24
+ association_filter_options(
15
25
  rexport_model.collection_from_association(association),
16
- :id,
17
26
  text_method,
18
- value.to_i
19
- )).html_safe,
20
- class: 'form-control'
27
+ value
28
+ )
21
29
  )
22
- when :datetime, nil
23
- '&nbsp;'.html_safe
24
- else
25
- text_field_tag(tag_name, value, class: 'form-control')
30
+ when :boolean
31
+ boolean_filter_select_tag(tag_name, value)
32
+ when :date, :integer, :string
33
+ text_field_tag(tag_name, value, class: FORM_TAG_CLASS)
26
34
  end
27
35
  end
36
+
37
+ private
38
+
39
+ def boolean_filter_select_tag(tag_name, value)
40
+ select_tag(tag_name, options_for_select(BOOLEAN_OPTIONS, value&.to_i), class: FORM_TAG_CLASS)
41
+ end
42
+
43
+ def association_filter_options(collection, text_method, value)
44
+ options_from_collection_for_select(collection, :id, text_method, value&.to_i)
45
+ end
46
+
47
+ def association_filter_select_tag(tag_name, options)
48
+ select_tag(tag_name, options, include_blank: true, class: FORM_TAG_CLASS)
49
+ end
28
50
  end
@@ -7,10 +7,10 @@
7
7
  </tr>
8
8
  <% for field in rexport_model.rexport_fields_array %>
9
9
  <tr class="<%= cycle('odd','even') %>">
10
- <td><%= check_box_tag "export[rexport_fields][#{rexport_model.field_path(field.name)}]", 1, @export.has_rexport_field?(rexport_model.field_path(field.name)) %></td>
10
+ <td><%= check_box_tag "export[rexport_fields][#{rexport_model.field_path(field.name)}]", 1, @export.rexport_field?(rexport_model.field_path(field.name)) %></td>
11
11
  <td class="row_title"><%= field.name.titleize %></td>
12
12
  <td class='row_title'>
13
- <%= filter_value_field(rexport_model, field) %>
13
+ <%= rexport_filter_tag(@export, rexport_model, field) %>
14
14
  </td>
15
15
  </tr>
16
16
  <% end %>
data/config/routes.rb CHANGED
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Rails.application.routes.draw do
2
4
  # singleton resources
3
5
  resource :export_item_sorting, only: :update
4
6
 
5
7
  # collection resources
6
- resources :export_items, only: %i(edit update destroy)
7
- resources :export_filters, only: %i(edit update destroy)
8
+ resources :export_items, only: %i[edit update destroy]
9
+ resources :export_filters, only: %i[edit update destroy]
8
10
  resources :exports do
9
11
  resources :export_filters, only: :new
10
12
  end
@@ -1,17 +1,38 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rexport
2
4
  class DataField
3
5
  include Comparable
4
- attr_accessor :name, :method, :type
6
+ attr_reader :name, :method, :type
5
7
 
6
8
  # Stores the name and method of the export data item
7
9
  def initialize(name, options = {})
8
- self.name = name.to_s
9
- self.method = options[:method].blank? ? self.name : options[:method].to_s
10
- self.type = options[:type]
10
+ @name = name.to_s
11
+ @method = options[:method].blank? ? self.name : options[:method].to_s
12
+ @type = options[:type]
13
+ end
14
+
15
+ # Sort by name
16
+ def <=>(other)
17
+ name <=> other.name
11
18
  end
12
19
 
13
- def <=>(rf)
14
- self.name <=> rf.name
20
+ # Returns the first association name from a method chain string. If the string does not contain
21
+ # the dot operator a nil is returned.
22
+ #
23
+ # Examples:
24
+ #
25
+ # "assocation.method" # => "association"
26
+ # "assocation_one.assocation_two.method" # => "assocation_one"
27
+ # "method" # => nil
28
+ def association_name
29
+ method[0..(first_dot_index - 1)] if first_dot_index.present?
30
+ end
31
+
32
+ private
33
+
34
+ def first_dot_index
35
+ @first_dot_index ||= method.index(".")
15
36
  end
16
37
  end
17
38
  end
@@ -1,4 +1,6 @@
1
- module Rexport #:nodoc:
1
+ # frozen_string_literal: true
2
+
3
+ module Rexport # :nodoc:
2
4
  module DataFields
3
5
  extend ActiveSupport::Concern
4
6
 
@@ -7,6 +9,7 @@ module Rexport #:nodoc:
7
9
  def get_klass_from_associations(*associations)
8
10
  associations.flatten!
9
11
  return self if associations.empty?
12
+
10
13
  reflect_on_association(associations.shift.to_sym).klass.get_klass_from_associations(associations)
11
14
  end
12
15
  end
@@ -14,21 +17,15 @@ module Rexport #:nodoc:
14
17
  # Return an array of formatted export values for the passed methods
15
18
  def export(*methods)
16
19
  methods.flatten.map do |method|
17
- case value = (eval("self.#{method}", binding) rescue nil)
18
- when Date, Time
19
- value.strftime("%m/%d/%y")
20
- when TrueClass
21
- 'Y'
22
- when FalseClass
23
- 'N'
24
- else value.to_s
25
- end
20
+ Rexport::Formatter.convert(instance_eval(method))
21
+ rescue NameError
22
+ ""
26
23
  end
27
24
  end
28
25
 
29
26
  # Returns string indicating this field is undefined
30
27
  def undefined_rexport_field
31
- 'UNDEFINED EXPORT FIELD'
28
+ "UNDEFINED EXPORT FIELD"
32
29
  end
33
30
  end
34
31
  end
@@ -1,4 +1,6 @@
1
- module Rexport #:nodoc:
1
+ # frozen_string_literal: true
2
+
3
+ module Rexport # :nodoc:
2
4
  module ExportFilterMethods
3
5
  extend ActiveSupport::Concern
4
6
 
@@ -12,23 +14,24 @@ module Rexport #:nodoc:
12
14
  end
13
15
 
14
16
  def attributes_for_copy
15
- attributes.slice('filter_field', 'value')
17
+ attributes.slice("filter_field", "value")
16
18
  end
17
19
 
18
20
  private
19
21
 
20
22
  def associated_object_value
21
- return 'UNDEFINED ASSOCIATION' unless filter_association
23
+ return "UNDEFINED ASSOCIATION" unless filter_association
24
+
22
25
  begin
23
26
  object = filter_association.klass.find(value)
24
- return object.respond_to?(:name) ? object.name : object.to_s
27
+ object.respond_to?(:name) ? object.name : object.to_s
25
28
  rescue ActiveRecord::RecordNotFound
26
- return 'ASSOCIATED OBJECT NOT FOUND'
29
+ "ASSOCIATED OBJECT NOT FOUND"
27
30
  end
28
31
  end
29
32
 
30
33
  def filter_association
31
- @filter_on_assocation ||= find_filter_association
34
+ @filter_association ||= find_filter_association
32
35
  end
33
36
 
34
37
  def find_filter_association
@@ -42,11 +45,11 @@ module Rexport #:nodoc:
42
45
  end
43
46
 
44
47
  def filter_path
45
- filter_field.split('.')[0..-2]
48
+ filter_field.split(".")[0..-2]
46
49
  end
47
50
 
48
51
  def filter_foreign_key
49
- filter_field.split('.').last
52
+ filter_field.split(".").last
50
53
  end
51
54
 
52
55
  def filter_on_associated_object?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rexport
2
4
  module ExportFiltersControllerMethods
3
5
  def destroy
@@ -1,4 +1,6 @@
1
- module Rexport #:nodoc:
1
+ # frozen_string_literal: true
2
+
3
+ module Rexport # :nodoc:
2
4
  module ExportItemMethods
3
5
  extend ActiveSupport::Concern
4
6
 
@@ -17,14 +19,14 @@ module Rexport #:nodoc:
17
19
  def resort(export_item_ids)
18
20
  transaction do
19
21
  export_item_ids.each_with_index do |id, index|
20
- find(id.gsub(/[^0-9]/, '')).update_attribute(:position, index + 1)
22
+ find(id.gsub(/[^0-9]/, "")).update_attribute(:position, index + 1)
21
23
  end
22
24
  end
23
25
  end
24
26
  end
25
27
 
26
28
  def attributes_for_copy
27
- attributes.slice('position', 'name', 'rexport_field')
29
+ attributes.slice("position", "name", "rexport_field")
28
30
  end
29
31
 
30
32
  private
@@ -34,7 +36,7 @@ module Rexport #:nodoc:
34
36
  end
35
37
 
36
38
  def generate_name_from_rexport_field
37
- rexport_field.split('.').last(2).map(&:titleize).join(' - ')
39
+ rexport_field.split(".").last(2).map(&:titleize).join(" - ")
38
40
  end
39
41
  end
40
42
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rexport
2
4
  module ExportItemSortingsControllerMethods
3
5
  def update
4
6
  ExportItem.resort(params[:sorted_items])
5
-
7
+
6
8
  respond_to do |format|
7
9
  format.js do
8
10
  head :ok
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rexport
2
4
  module ExportItemsControllerMethods
3
5
  def edit
@@ -6,7 +8,7 @@ module Rexport
6
8
 
7
9
  def update
8
10
  if export_item.update(export_item_params)
9
- redirect_to export_path(export_item.export), notice: 'ExportItem was successfully updated.'
11
+ redirect_to export_path(export_item.export), notice: "ExportItem was successfully updated."
10
12
  else
11
13
  render :edit
12
14
  end
@@ -1,6 +1,8 @@
1
- require 'csv'
1
+ # frozen_string_literal: true
2
2
 
3
- module Rexport #:nodoc:
3
+ require "csv"
4
+
5
+ module Rexport # :nodoc:
4
6
  module ExportMethods
5
7
  extend ActiveSupport::Concern
6
8
 
@@ -18,7 +20,7 @@ module Rexport #:nodoc:
18
20
 
19
21
  module ClassMethods
20
22
  def models
21
- %w(override_this_method)
23
+ %w[override_this_method]
22
24
  end
23
25
  end
24
26
 
@@ -28,12 +30,7 @@ module Rexport #:nodoc:
28
30
 
29
31
  # Returns a string with the export data
30
32
  def to_s
31
- String.new.tap do |result|
32
- result << header * '|' << "\n"
33
- records.each do |record|
34
- result << record * '|' << "\n"
35
- end
36
- end
33
+ records.unshift(header).map { |line| line.join("|") }.join("\n")
37
34
  end
38
35
 
39
36
  # Returns a csv string with the export data
@@ -80,33 +77,35 @@ module Rexport #:nodoc:
80
77
  # Returns a class based on a path array
81
78
  def get_klass_from_path(path, klass = export_model)
82
79
  return klass unless (association_name = path.shift)
80
+
83
81
  get_klass_from_path(path, klass.reflect_on_association(association_name.to_sym).klass)
84
82
  end
85
83
 
86
- def has_rexport_field?(rexport_field)
84
+ def has_rexport_field?(rexport_field) # rubocop:disable Naming/PredicateName
85
+ ActiveSupport::Deprecation.warn("Calling #has_rexport_field? is deprecated. Use #rexport_field? instead")
86
+ rexport_field?(rexport_field)
87
+ end
88
+
89
+ def rexport_field?(rexport_field)
87
90
  rexport_fields.include?(rexport_field)
88
91
  end
89
92
 
90
- def rexport_fields=(rexport_fields)
91
- @rexport_fields = if rexport_fields.respond_to?(:keys)
92
- @set_position = false
93
- rexport_fields.keys.map(&:to_s)
94
- else
95
- @set_position = true
96
- rexport_fields.map(&:to_s)
97
- end
93
+ # Stores rexport_field names to update the export_items association after save
94
+ # Expects fields to be a hash with field names as the keys or an array of field names:
95
+ # { "field_one" => "1", "field_two" => "1" }
96
+ # ["field_one", "field_two"]
97
+ def rexport_fields=(fields)
98
+ @rexport_fields = extract_rexport_fields(fields).map(&:to_s)
98
99
  end
99
100
 
100
101
  def export_filter_attributes=(attributes)
101
102
  attributes.each do |field, value|
102
103
  if value.blank?
103
- filter = export_filters.find_by(filter_field: field)
104
- filter.destroy if filter
104
+ export_filters.find_by(filter_field: field)&.destroy
105
105
  elsif new_record?
106
106
  export_filters.build(filter_field: field, value: value)
107
107
  else
108
- filter = export_filters.find_or_create_by(filter_field: field)
109
- filter.update_attribute(:value, value)
108
+ export_filters.find_or_create_by(filter_field: field).update_attribute(:value, value)
110
109
  end
111
110
  end
112
111
  end
@@ -140,31 +139,33 @@ module Rexport #:nodoc:
140
139
 
141
140
  def get_rexport_models(model, results = [], path = nil)
142
141
  return unless model.include?(Rexport::DataFields)
142
+
143
143
  results << RexportModel.new(model, path: path)
144
144
  get_associations(model).each do |associated_model|
145
145
  # prevent infinite loop by checking if this class is already in the results set
146
146
  next if results.detect { |result| result.klass == associated_model.klass }
147
- get_rexport_models(associated_model.klass, results, [path, associated_model.name].compact * '.')
147
+
148
+ get_rexport_models(associated_model.klass, results, [path, associated_model.name].compact * ".")
148
149
  end
149
- return results
150
+ results
150
151
  end
151
152
 
152
153
  def get_associations(model)
153
- %i(belongs_to has_one).map do |type|
154
+ %i[belongs_to has_one].map do |type|
154
155
  model.reflect_on_all_associations(type)
155
156
  end.flatten.reject(&:polymorphic?)
156
157
  end
157
158
 
158
159
  def build_include
159
- root = Rexport::TreeNode.new('root')
160
- (rexport_methods + filter_fields).select {|m| m.include?('.')}.each do |method|
161
- root.add_child(method.split('.').values_at(0..-2))
160
+ root = Rexport::TreeNode.new("root")
161
+ (rexport_methods + filter_fields).select { |m| m.include?(".") }.each do |method|
162
+ root.add_child(method.split(".").values_at(0..-2))
162
163
  end
163
164
  root.to_include
164
165
  end
165
166
 
166
167
  def build_conditions
167
- Hash.new.tap do |conditions|
168
+ {}.tap do |conditions|
168
169
  export_filters.each do |filter|
169
170
  conditions[get_database_field(filter.filter_field)] = filter.value
170
171
  end
@@ -172,7 +173,7 @@ module Rexport #:nodoc:
172
173
  end
173
174
 
174
175
  def get_database_field(field)
175
- path = field.split('.')
176
+ path = field.split(".")
176
177
  field = path.pop
177
178
  "#{get_klass_from_path(path).table_name}.#{field}"
178
179
  end
@@ -194,27 +195,38 @@ module Rexport #:nodoc:
194
195
  end
195
196
 
196
197
  def save_export_items
197
- export_items.each do |export_item|
198
- unless rexport_fields.include?(export_item.rexport_field)
199
- export_item.destroy
200
- end
201
- end
198
+ export_items.where.not(rexport_field: rexport_fields).destroy_all
202
199
 
203
200
  rexport_fields.each.with_index(1) do |rexport_field, position|
204
- export_item = export_items.detect { |i| i.rexport_field == rexport_field } || export_items.create(rexport_field: rexport_field)
205
- export_item.update_attribute(:position, position) if set_position
201
+ find_or_create_export_item(rexport_field).tap do |export_item|
202
+ export_item.update_attribute(:position, position) if set_position
203
+ end
206
204
  end
207
205
 
208
- return true
206
+ true
207
+ end
208
+
209
+ # Uses array find to search in memory export_items assocation instead of performing a SQL query on every iteration
210
+ def find_or_create_export_item(rexport_field)
211
+ export_items.find { |export_item| export_item.rexport_field == rexport_field } || export_items.create(rexport_field: rexport_field)
209
212
  end
210
213
 
211
214
  def attributes_for_copy
212
- attributes.slice('model_class_name', 'description').merge(name: find_unique_name(name))
215
+ attributes.slice("model_class_name", "description").merge(name: find_unique_name(name))
213
216
  end
214
217
 
215
218
  def find_unique_name(original_name, suffix = 0)
216
- new_name = suffix == 0 ? "#{original_name} Copy" : "#{original_name} Copy [#{suffix}]"
217
- self.class.find_by(name: new_name) ? find_unique_name(original_name, suffix += 1) : new_name
219
+ new_name = suffix.zero? ? "#{original_name} Copy" : "#{original_name} Copy [#{suffix}]"
220
+ self.class.find_by(name: new_name) ? find_unique_name(original_name, suffix + 1) : new_name
221
+ end
222
+
223
+ def extract_rexport_fields(fields)
224
+ # When fields is a hash return the keys and do not update export_item positions on save
225
+ return fields.keys if fields.respond_to?(:keys)
226
+
227
+ # When fields is an array update export item positions on save
228
+ @set_position = true
229
+ fields
218
230
  end
219
231
 
220
232
  def set_position
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rexport
2
4
  module ExportsControllerMethods
3
5
  def index
@@ -9,7 +11,7 @@ module Rexport
9
11
 
10
12
  respond_to do |format|
11
13
  format.html # show.html.erb
12
- format.csv { send_data(export.to_csv, type: export_content_type, filename: filename) }
14
+ format.csv { send_data(export.to_csv, filename: filename) }
13
15
  end
14
16
  end
15
17
 
@@ -25,7 +27,7 @@ module Rexport
25
27
  @export = params[:original_export_id] ? Export.find(params[:original_export_id]).copy : Export.new(export_params)
26
28
 
27
29
  if @export.save
28
- redirect_to @export, notice: 'Export was successfully created.'
30
+ redirect_to @export, notice: "Export was successfully created."
29
31
  else
30
32
  render :new
31
33
  end
@@ -33,7 +35,7 @@ module Rexport
33
35
 
34
36
  def update
35
37
  if export.update(export_params)
36
- redirect_to export, notice: 'Export was successfully updated.'
38
+ redirect_to export, notice: "Export was successfully updated."
37
39
  else
38
40
  render :edit
39
41
  end
@@ -60,17 +62,15 @@ module Rexport
60
62
  :name,
61
63
  :model_class_name,
62
64
  :description,
63
- rexport_fields: {},
64
- export_filter_attributes: {}
65
+ {
66
+ rexport_fields: {},
67
+ export_filter_attributes: {}
68
+ }
65
69
  ]
66
70
  end
67
71
 
68
- def export_content_type
69
- request.user_agent =~ /windows/i ? 'application/vnd.ms-excel' : 'text/csv'
70
- end
71
-
72
72
  def filename
73
- "#{export.model_class_name}_#{export.name.gsub(/ /, '_')}_#{Time.now.strftime('%Y%m%d')}.csv"
73
+ "#{export.model_class_name}_#{export.name.tr(' ', '_')}_#{Time.current.strftime('%Y%m%d')}.csv"
74
74
  end
75
75
  end
76
76
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rexport
4
+ module Formatter
5
+ def self.convert(value)
6
+ case value
7
+ when Date, Time
8
+ value.strftime("%m/%d/%y")
9
+ when TrueClass
10
+ "Y"
11
+ when FalseClass
12
+ "N"
13
+ else
14
+ value.to_s
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,15 +1,19 @@
1
- module Rexport #:nodoc:
1
+ # frozen_string_literal: true
2
+
3
+ module Rexport # :nodoc:
2
4
  class RexportModel
3
5
  attr_accessor :klass, :path
4
6
 
7
+ delegate :name, to: :klass
8
+
5
9
  def initialize(klass, path: nil)
6
10
  self.klass = klass
7
- self.path = path.to_s unless path.blank?
11
+ self.path = path&.to_s
8
12
  initialize_rexport_fields
9
13
  end
10
14
 
11
15
  def rexport_fields
12
- @rexport_fields ||= HashWithIndifferentAccess.new
16
+ @rexport_fields ||= ActiveSupport::HashWithIndifferentAccess.new
13
17
  end
14
18
 
15
19
  def rexport_fields_array
@@ -17,7 +21,7 @@ module Rexport #:nodoc:
17
21
  end
18
22
 
19
23
  def field_path(field_name)
20
- [path, field_name].compact * '.'
24
+ [path, field_name].compact * "."
21
25
  end
22
26
 
23
27
  def collection_from_association(association)
@@ -29,13 +33,7 @@ module Rexport #:nodoc:
29
33
  end
30
34
 
31
35
  def filter_column(field)
32
- return field.method unless field.method.include?('.')
33
- association = field.method.split('.').first
34
- klass.reflect_on_association(association.to_sym).foreign_key
35
- end
36
-
37
- def name
38
- klass.name
36
+ foreign_key_for(field.association_name) || field.method
39
37
  end
40
38
 
41
39
  # Adds a data item to rexport_fields
@@ -55,33 +53,23 @@ module Rexport #:nodoc:
55
53
  # :filter - if true will send type: :association to add_report_field
56
54
  def add_association_methods(options = {})
57
55
  options.stringify_keys!
58
- options.assert_valid_keys(%w(associations methods filter))
59
-
60
- methods = options.reverse_merge('methods' => 'name')['methods']
61
- methods = [methods] if methods.kind_of?(String)
62
-
63
- associations = options['associations']
64
- associations = [associations] if associations.kind_of?(String)
56
+ options.assert_valid_keys(%w[associations methods filter])
65
57
 
66
- type = options['filter'] ? :association : nil
67
-
68
- associations.each do |association|
69
- methods.each do |method|
70
- add_rexport_field("#{association}_#{method}", method: "#{association}.#{method}", type: type)
71
- end
72
- end
58
+ add_rexport_fields_for(
59
+ associations: [options["associations"]].flatten,
60
+ methods: [options["methods"] || "name"].flatten,
61
+ type: (options["filter"] ? :association : nil)
62
+ )
73
63
  end
74
64
 
75
65
  # Returns an array of export methods corresponding with field_names
76
66
  def get_rexport_methods(*field_names)
77
67
  field_names.flatten.map do |f|
78
- begin
79
- components = f.to_s.split('.')
80
- field_name = components.pop
81
- components.push(get_rexport_model(components).get_rexport_method(field_name)) * '.'
82
- rescue NoMethodError
83
- 'undefined_rexport_field'
84
- end
68
+ components = f.to_s.split(".")
69
+ field_name = components.pop
70
+ components.push(get_rexport_model(components).get_rexport_method(field_name)) * "."
71
+ rescue NoMethodError
72
+ "undefined_rexport_field"
85
73
  end
86
74
  end
87
75
 
@@ -101,15 +89,23 @@ module Rexport #:nodoc:
101
89
 
102
90
  # Returns the export method for a given field_name
103
91
  def get_rexport_method(field_name)
104
- if rexport_fields[field_name]
105
- rexport_fields[field_name].method
106
- else
107
- raise NoMethodError
108
- end
92
+ rexport_fields[field_name]&.method || raise(NoMethodError)
109
93
  end
110
94
 
111
95
  private
112
96
 
97
+ def add_rexport_fields_for(associations:, methods:, type:)
98
+ associations.each do |association|
99
+ methods.each do |method|
100
+ add_rexport_field("#{association}_#{method}", method: "#{association}.#{method}", type: type)
101
+ end
102
+ end
103
+ end
104
+
105
+ def foreign_key_for(association_name)
106
+ klass.reflect_on_association(association_name).foreign_key if association_name.present?
107
+ end
108
+
113
109
  def initialize_rexport_fields
114
110
  klass.content_columns.each { |field| add_rexport_field(field.name, type: field.type) }
115
111
  klass.initialize_local_rexport_fields(self) if klass.respond_to?(:initialize_local_rexport_fields)
@@ -1,4 +1,6 @@
1
- module Rexport #:nodoc:
1
+ # frozen_string_literal: true
2
+
3
+ module Rexport # :nodoc:
2
4
  # A basic tree for building up ActiveRecord find :include parameters
3
5
  class TreeNode
4
6
  attr_accessor :name, :children
@@ -13,7 +15,8 @@ module Rexport #:nodoc:
13
15
  # Add one or more children to the tree
14
16
  def add_child(*names)
15
17
  names.flatten!
16
- return unless name = names.shift
18
+ return unless (name = names.shift)
19
+
17
20
  node = children.find { |c| c.name == name }
18
21
  node ? node.add_child(names) : (children << TreeNode.new(name, names))
19
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rexport
2
- VERSION = '1.3.0'
4
+ VERSION = "1.4.0"
3
5
  end
data/lib/rexport.rb CHANGED
@@ -1,19 +1,22 @@
1
- require 'rexport/data_field'
2
- require 'rexport/data_fields'
3
- require 'rexport/export_filter_methods'
4
- require 'rexport/export_filters_controller_methods'
5
- require 'rexport/export_item_methods'
6
- require 'rexport/export_item_sortings_controller_methods'
7
- require 'rexport/export_items_controller_methods'
8
- require 'rexport/export_methods'
9
- require 'rexport/exports_controller_methods'
10
- require 'rexport/rexport_model'
11
- require 'rexport/tree_node'
1
+ # frozen_string_literal: true
2
+
3
+ require "rexport/data_field"
4
+ require "rexport/data_fields"
5
+ require "rexport/export_filter_methods"
6
+ require "rexport/export_filters_controller_methods"
7
+ require "rexport/export_item_methods"
8
+ require "rexport/export_item_sortings_controller_methods"
9
+ require "rexport/export_items_controller_methods"
10
+ require "rexport/export_methods"
11
+ require "rexport/exports_controller_methods"
12
+ require "rexport/formatter"
13
+ require "rexport/rexport_model"
14
+ require "rexport/tree_node"
12
15
 
13
16
  module Rexport
14
17
  SAMPLE_SIZE = 5
15
18
 
16
19
  class Engine < ::Rails::Engine
17
- config.paths['app/views'] << File.join(File.dirname(__FILE__),'../app/views')
20
+ config.paths["app/views"] << File.join(File.dirname(__FILE__), "../app/views")
18
21
  end
19
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rexport
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Baldwin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-01-31 00:00:00.000000000 Z
12
+ date: 2023-03-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -62,6 +62,7 @@ files:
62
62
  - lib/rexport/export_items_controller_methods.rb
63
63
  - lib/rexport/export_methods.rb
64
64
  - lib/rexport/exports_controller_methods.rb
65
+ - lib/rexport/formatter.rb
65
66
  - lib/rexport/rexport_model.rb
66
67
  - lib/rexport/tree_node.rb
67
68
  - lib/rexport/version.rb