Module: DutyFree::Extensions::ClassMethods
- Defined in:
- lib/duty_free/extensions.rb
Overview
:nodoc:
Instance Method Summary collapse
-
#df_export(is_with_data = true, import_template = nil, use_inner_joins = false) ⇒ Object
Export at least column header, and optionally include all existing data as well.
- #df_import(data, import_template = nil, insert_only = false) ⇒ Object
Instance Method Details
#df_export(is_with_data = true, import_template = nil, use_inner_joins = false) ⇒ Object
Export at least column header, and optionally include all existing data as well
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/duty_free/extensions.rb', line 22 def df_export(is_with_data = true, import_template = nil, use_inner_joins = false) use_inner_joins = true unless respond_to?(:left_joins) # In case they are only supplying the columns hash if is_with_data.is_a?(Hash) && !import_template import_template = is_with_data is_with_data = true end import_template ||= if constants.include?(:IMPORT_TEMPLATE) self::IMPORT_TEMPLATE else suggest_template(0, false, false) end # Friendly column names that end up in the first row of the CSV # Required columns get prefixed with a * requireds = (import_template[:required] || []) rows = ::DutyFree::Extensions._template_columns(self, import_template).map do |col| is_required = requireds.include?(col) col = col.to_s.titleize # Alias-ify the full column names aliases = (import_template[:as] || []) aliases.each do |k, v| if col.start_with?(v) col = k + col[v.length..-1] break end end (is_required ? '* ' : '') + col end rows = [rows] if is_with_data order_by = [] order_by << ['_', primary_key] if primary_key all = import_template[:all] || import_template[:all!] # Automatically create a JOINs strategy and select list to get back all related rows template_cols, template_joins = ::DutyFree::Extensions._recurse_def(self, all, import_template, nil, order_by) # We do this so early here because it removes type objects from template_joins so then # template_joins can immediately be used for inner and outer JOINs. our_names = [[self, '_']] + ::DutyFree::Util._recurse_arel(template_joins) relation = use_inner_joins ? joins(template_joins) : left_joins(template_joins) # So we can properly create the SELECT list, create a mapping between our # column alias prefixes and the aliases AREL creates. # %%% If with Rails 3.1 and older you get "NoMethodError: undefined method `eq' for nil:NilClass" # when trying to call relation.arel, then somewhere along the line while navigating a has_many # relationship it can't find the proper foreign key. core = relation.arel.ast.cores.first # Accommodate AR < 3.2 arel_alias_names = if core.froms.is_a?(Arel::Table) # All recent versions of AR have #source which brings up an Arel::Nodes::JoinSource ::DutyFree::Util._recurse_arel(core.source) else # With AR < 3.2, "froms" brings up the top node, an Arel::Nodes::InnerJoin ::DutyFree::Util._recurse_arel(core.froms) end # Make sure our_names lines up with the arel_alias_name by comparing the ActiveRecord type. # AR < 5.0 behaves differently than newer versions, and AR 5.0 and 5.1 have a bug in the # way the types get determined, so if we want perfect results then we must compensate for # these foibles. Thank goodness that AR 5.2 and later find the proper type and make it # available through the type_caster object, which is what we use when building the list of # arel_alias_names. mapping = arel_alias_names.each_with_object({}) do |arel_alias_name, s| if our_names.first&.first == arel_alias_name.first s[our_names.first.last] = arel_alias_name.last our_names.shift end s end relation = (order_by.empty? ? relation : relation.order(order_by.map { |o| "#{mapping[o.first]}.#{o.last}" })) # puts mapping.inspect # puts relation.dup.select(template_cols.map { |x| x.to_s(mapping) }).to_sql # Allow customisation of query before running it relation = yield(relation, mapping) if block_given? relation&.select(template_cols.map { |x| x.to_s(mapping) })&.each do |result| rows << ::DutyFree::Extensions._template_columns(self, import_template).map do |col| value = result.send(col) case value when true 'Yes' when false 'No' else value.to_s end end end end rows end |
#df_import(data, import_template = nil, insert_only = false) ⇒ Object
115 116 117 |
# File 'lib/duty_free/extensions.rb', line 115 def df_import(data, import_template = nil, insert_only = false) ::DutyFree::Extensions.import(self, data, import_template, insert_only) end |