module Rexport::ExportMethods
Public Instance Methods
# File lib/rexport/export_methods.rb, line 117 def copy self.class.create(attributes_for_copy) do |new_export| export_items.ordered.each { |item| new_export.export_items.build(item.attributes_for_copy) } export_filters.each { |filter| new_export.export_filters.build(filter.attributes_for_copy) } end end
# File lib/rexport/export_methods.rb, line 101 def export_filter_attributes=(attributes) attributes.each do |field, value| if value.blank? export_filters.find_by(filter_field: field)&.destroy elsif new_record? export_filters.build(filter_field: field, value: value) else export_filters.find_or_create_by(filter_field: field).update_attribute(:value, value) end end end
Returns the export model class
# File lib/rexport/export_methods.rb, line 53 def export_model model_class_name.constantize end
# File lib/rexport/export_methods.rb, line 113 def filter_value(filter_field) export_filters.detect { |f| f.filter_field == filter_field }&.value end
# File lib/rexport/export_methods.rb, line 27 def full_name "#{model_class_name.pluralize} - #{name}" end
Returns a class based on a path array
# File lib/rexport/export_methods.rb, line 78 def get_klass_from_path(path, klass = export_model) return klass unless (association_name = path.shift) get_klass_from_path(path, klass.reflect_on_association(association_name.to_sym).klass) end
# File lib/rexport/export_methods.rb, line 84 def has_rexport_field?(rexport_field) # rubocop:disable Naming/PredicateName ActiveSupport::Deprecation.warn("Calling #has_rexport_field? is deprecated. Use #rexport_field? instead") rexport_field?(rexport_field) end
Returns an array with the header names from the associated export_items
# File lib/rexport/export_methods.rb, line 48 def header export_items.ordered.map(&:name) end
Returns the records for the export
# File lib/rexport/export_methods.rb, line 68 def records @records ||= get_records end
# File lib/rexport/export_methods.rb, line 89 def rexport_field?(rexport_field) rexport_fields.include?(rexport_field) end
Stores rexport_field names to update the export_items association after save Expects fields to be a hash with field names as the keys or an array of field names: { “field_one” => “1”, “field_two” => “1” }
- “field_one”, “field_two”
# File lib/rexport/export_methods.rb, line 97 def rexport_fields=(fields) @rexport_fields = extract_rexport_fields(fields).map(&:to_s) end
Returns a RexportModel
for the current export_model
# File lib/rexport/export_methods.rb, line 58 def rexport_model @rexport_model ||= RexportModel.new(export_model) end
Returns an array of RexportModels including export_model
and associated rexport capable models
# File lib/rexport/export_methods.rb, line 63 def rexport_models @rexport_models ||= get_rexport_models(export_model) end
Returns a limited number of records for the export
# File lib/rexport/export_methods.rb, line 73 def sample_records get_records(Rexport::SAMPLE_SIZE) end
Returns a csv string with the export data
# File lib/rexport/export_methods.rb, line 37 def to_csv(objects = nil) seed_records(objects) unless objects.nil? CSV.generate do |csv| csv << header records.each do |record| csv << record end end end
Returns a string with the export data
# File lib/rexport/export_methods.rb, line 32 def to_s records.unshift(header).map { |line| line.join("|") }.join("\n") end
Private Instance Methods
# File lib/rexport/export_methods.rb, line 214 def attributes_for_copy attributes.slice("model_class_name", "description").merge(name: find_unique_name(name)) end
# File lib/rexport/export_methods.rb, line 167 def build_conditions {}.tap do |conditions| export_filters.each do |filter| conditions[get_database_field(filter.filter_field)] = filter.value end end end
# File lib/rexport/export_methods.rb, line 159 def build_include root = Rexport::TreeNode.new("root") (rexport_methods + filter_fields).select { |m| m.include?(".") }.each do |method| root.add_child(method.split(".").values_at(0..-2)) end root.to_include end
# File lib/rexport/export_methods.rb, line 223 def extract_rexport_fields(fields) # When fields is a hash return the keys and do not update export_item positions on save return fields.keys if fields.respond_to?(:keys) # When fields is an array update export item positions on save @set_position = true fields end
# File lib/rexport/export_methods.rb, line 193 def filter_fields export_filters.map(&:filter_field) end
Uses array find to search in memory export_items assocation instead of performing a SQL query on every iteration
# File lib/rexport/export_methods.rb, line 210 def find_or_create_export_item(rexport_field) export_items.find { |export_item| export_item.rexport_field == rexport_field } || export_items.create(rexport_field: rexport_field) end
# File lib/rexport/export_methods.rb, line 218 def find_unique_name(original_name, suffix = 0) new_name = suffix.zero? ? "#{original_name} Copy" : "#{original_name} Copy [#{suffix}]" self.class.find_by(name: new_name) ? find_unique_name(original_name, suffix + 1) : new_name end
# File lib/rexport/export_methods.rb, line 153 def get_associations(model) %i[belongs_to has_one].map do |type| model.reflect_on_all_associations(type) end.flatten.reject(&:polymorphic?) end
# File lib/rexport/export_methods.rb, line 175 def get_database_field(field) path = field.split(".") field = path.pop "#{get_klass_from_path(path).table_name}.#{field}" end
# File lib/rexport/export_methods.rb, line 136 def get_export_values(objects) objects.map { |object| object.export(rexport_methods) } end
# File lib/rexport/export_methods.rb, line 126 def get_records(limit = nil) get_export_values(export_model.where(build_conditions).includes(build_include).limit(limit)) rescue ActiveRecord::StatementInvalid => e [[e.message]] end
# File lib/rexport/export_methods.rb, line 140 def get_rexport_models(model, results = [], path = nil) return unless model.include?(Rexport::DataFields) results << RexportModel.new(model, path: path) get_associations(model).each do |associated_model| # prevent infinite loop by checking if this class is already in the results set next if results.detect { |result| result.klass == associated_model.klass } get_rexport_models(associated_model.klass, results, [path, associated_model.name].compact * ".") end results end
# File lib/rexport/export_methods.rb, line 189 def ordered_rexport_fields export_items.ordered.map(&:rexport_field) end
# File lib/rexport/export_methods.rb, line 185 def rexport_fields @rexport_fields ||= export_items.map(&:rexport_field) end
# File lib/rexport/export_methods.rb, line 181 def rexport_methods @rexport_methods ||= rexport_model.get_rexport_methods(ordered_rexport_fields) end
# File lib/rexport/export_methods.rb, line 197 def save_export_items export_items.where.not(rexport_field: rexport_fields).destroy_all rexport_fields.each.with_index(1) do |rexport_field, position| find_or_create_export_item(rexport_field).tap do |export_item| export_item.update_attribute(:position, position) if set_position end end true end
# File lib/rexport/export_methods.rb, line 132 def seed_records(objects) @records = get_export_values(objects) end
# File lib/rexport/export_methods.rb, line 232 def set_position @set_position ||= false end