lib/spreadsheet_architect/utils.rb in spreadsheet_architect-2.1.2 vs lib/spreadsheet_architect/utils.rb in spreadsheet_architect-3.0.0
- old
+ new
@@ -1,147 +1,136 @@
module SpreadsheetArchitect
module Utils
- def self.str_humanize(str, capitalize = true)
- str = str.sub(/\A_+/, '').gsub(/[_\.]/,' ').sub(' rescue nil','')
- if capitalize
- str = str.gsub(/(\A|\ )\w/){|x| x.upcase}
+ def self.get_cell_data(options, klass)
+ if options[:data] && options[:instances]
+ raise SpreadsheetArchitect::Exceptions::MultipleDataSourcesError
+ elsif options[:data]
+ data = options[:data]
end
- return str
- end
- def self.get_cell_data(options={}, klass)
- self.check_options_types
+ if !options[:data] && options[:headers] == true
+ headers = []
+ needs_headers = true
+ elsif options[:headers].is_a?(Array)
+ headers = options[:headers]
+ else
+ headers = false
+ end
- if klass.name == 'SpreadsheetArchitect'
- if !options[:data]
- raise SpreadsheetArchitect::Exceptions::NoDataError
- end
-
- if options[:headers] && options[:headers].is_a?(Array) && !options[:headers].empty?
- headers = options[:headers]
- else
- headers = false
- end
-
- data = options[:data]
+ if options[:column_types]
+ column_types = options[:column_types]
else
- has_custom_columns = options[:spreadsheet_columns] || klass.instance_methods.include?(:spreadsheet_columns)
+ column_types = []
+ needs_column_types = true
+ end
- if !options[:instances] && defined?(ActiveRecord) && klass.ancestors.include?(ActiveRecord::Base)
- options[:instances] = klass.where(nil).to_a # triggers the relation call, not sure how this works but it does
- end
-
+ if !data
if !options[:instances]
- raise SpreadsheetArchitect::Exceptions::NoInstancesError
+ if is_ar_model?(klass)
+ options[:instances] = klass.where(nil).to_a # triggers the relation call, not sure how this works but it does
+ else
+ raise SpreadsheetArchitect::Exceptions::NoDataError
+ end
end
- if options[:headers].nil?
- headers = klass::SPREADSHEET_OPTIONS[:headers] if defined?(klass::SPREADSHEET_OPTIONS)
- headers ||= SpreadsheetArchitect.default_options[:headers]
- elsif options[:headers].is_a?(Array)
- headers = options[:headers]
- end
-
- if headers == false || headers.is_a?(Array)
- needs_headers = false
- else
- headers = true
- needs_headers = true
- end
-
- if has_custom_columns
- headers = [] if needs_headers
- columns = []
- array = options[:spreadsheet_columns] || (options[:instances].empty? ? [] : options[:instances].first.spreadsheet_columns)
- array.each_with_index do |x,i|
- if x.is_a?(Array)
- headers.push(x[0].to_s) if needs_headers
- columns.push x[1]
- else
- headers.push(str_humanize(x.to_s)) if needs_headers
- columns.push x
- end
+ if !options[:spreadsheet_columns] && klass != SpreadsheetArchitect && !klass.instance_methods.include?(:spreadsheet_columns)
+ if is_ar_model?(klass)
+ the_column_names = klass.column_names
+ headers = the_column_names.map{|x| str_titleize(x)} if needs_headers
+ columns = the_column_names.map{|x| x.to_sym}
+ else
+ raise SpreadsheetArchitect::Exceptions::SpreadsheetColumnsNotDefinedError.new(klass)
end
- elsif !has_custom_columns && defined?(ActiveRecord) && klass.ancestors.include?(ActiveRecord::Base)
- ignored_columns = ["id","created_at","updated_at","deleted_at"]
- the_column_names = (klass.column_names - ignored_columns)
- headers = the_column_names.map{|x| str_humanize(x)} if needs_headers
- columns = the_column_names.map{|x| x.to_sym}
- else
- raise SpreadsheetArchitect::Exceptions::SpreadsheetColumnsNotDefinedError, klass
end
data = []
options[:instances].each do |instance|
- if has_custom_columns && !options[:spreadsheet_columns]
+ if columns
+ data.push columns.map{|col| col.is_a?(Symbol) ? instance.instance_eval(col.to_s) : col}
+ else
row_data = []
- instance.spreadsheet_columns.each do |x|
+
+ if !options[:spreadsheet_columns]
+ if klass == SpreadsheetArchitect && !instance.respond_to?(:spreadsheet_columns)
+ raise SpreadsheetArchitect::Exceptions::SpreadsheetColumnsNotDefinedError.new(instance.class)
+ else
+ instance_cols = instance.spreadsheet_columns
+ end
+ else
+ instance_cols = options[:spreadsheet_columns].call(instance)
+ end
+
+ instance_cols.each_with_index do |x,i|
if x.is_a?(Array)
+ headers.push(x[0].to_s) if needs_headers
row_data.push(x[1].is_a?(Symbol) ? instance.instance_eval(x[1].to_s) : x[1])
+ if needs_column_types
+ column_types[i] = x[2]
+ end
else
+ headers.push(str_titleize(x.to_s)) if needs_headers
row_data.push(x.is_a?(Symbol) ? instance.instance_eval(x.to_s) : x)
end
end
+
data.push row_data
- else
- data.push columns.map{|col| col.is_a?(Symbol) ? instance.instance_eval(col.to_s) : col}
+
+ needs_headers = false
+ needs_column_types = false
end
+
end
end
if headers && !headers[0].is_a?(Array)
headers = [headers]
end
- return options.merge(headers: headers, data: data, column_types: options[:column_types])
+ if column_types.compact.empty?
+ column_types = nil
+ end
+
+ return options.merge(headers: headers, data: data, column_types: column_types)
end
- def self.get_options(options={}, klass)
- if options[:headers]
- if defined?(klass::SPREADSHEET_OPTIONS)
- header_style = deep_clone(SpreadsheetArchitect.default_options[:header_style]).merge(klass::SPREADSHEET_OPTIONS[:header_style] || {})
+ def self.get_options(options, klass)
+ verify_option_types(options)
+
+ if defined?(klass::SPREADSHEET_OPTIONS)
+ if klass::SPREADSHEET_OPTIONS.is_a?(Hash)
+ options = SpreadsheetArchitect.default_options.merge(
+ klass::SPREADSHEET_OPTIONS.merge(options)
+ )
else
- header_style = deep_clone(SpreadsheetArchitect.default_options[:header_style])
+ raise SpreadsheetArchitect::Exceptions::InvalidTypeError.new("#{klass}::SPREADSHEET_OPTIONS constant")
end
-
- if options[:header_style]
- header_style.merge!(options[:header_style])
- elsif options[:header_style] == false
- header_style = false
- end
else
- header_style = false
+ options = SpreadsheetArchitect.default_options.merge(options)
end
- if options[:row_style] == false
- row_style = false
- else
- if defined?(klass::SPREADSHEET_OPTIONS)
- row_style = deep_clone(SpreadsheetArchitect.default_options[:row_style]).merge(klass::SPREADSHEET_OPTIONS[:row_style] || {})
+ if !options[:headers]
+ options[:header_style] = false
+ end
+
+ if !options[:sheet_name]
+ if klass == SpreadsheetArchitect
+ options[:sheet_name] = 'Sheet1'
else
- row_style = deep_clone(SpreadsheetArchitect.default_options[:row_style])
- end
+ options[:sheet_name] = klass.name
- if options[:row_style]
- row_style.merge!(options[:row_style])
+ if options[:sheet_name].respond_to?(:pluralize)
+ options[:sheet_name] = options[:sheet_name].pluralize
+ end
end
end
- if defined?(klass::SPREADSHEET_OPTIONS)
- sheet_name = options[:sheet_name] || klass::SPREADSHEET_OPTIONS[:sheet_name] || SpreadsheetArchitect.default_options[:sheet_name]
- else
- sheet_name = options[:sheet_name] || SpreadsheetArchitect.default_options[:sheet_name]
- end
-
- sheet_name ||= (klass.name == 'SpreadsheetArchitect' ? 'Sheet1' : klass.name)
-
- return options.merge(header_style: header_style, row_style: row_style, sheet_name: sheet_name)
+ return options
end
def self.convert_styles_to_ods(styles={})
styles = {} unless styles.is_a?(Hash)
- styles = self.stringify_keys(styles)
+ styles = stringify_keys(styles)
property_styles = {}
text_styles = {}
text_styles['font-weight'] = styles.delete('bold') ? 'bold' : styles.delete('font-weight')
@@ -173,51 +162,57 @@
return property_styles
end
private
- def self.deep_clone(x)
- Marshal.load(Marshal.dump(x))
+ def self.is_ar_model?(klass)
+ defined?(ActiveRecord) && klass.ancestors.include?(ActiveRecord::Base)
end
- def self.check_type(options, option_name, type)
- unless options[option_name].nil?
- valid = false
+ def self.str_titleize(str)
+ str = str.sub(/\A_+/, '')
+ .gsub(/[_\.]/,' ')
+ .sub(' rescue nil','')
+ .gsub(/(\A|\ )\w/){|x| x.upcase}
+ return str
+ end
+
+ def self.check_option_type(options, option_name, type)
+ val = options[option_name]
+
+ if val
if type.is_a?(Array)
- valid = type.any?{|t| options[option_name].is_a?(t)}
- elsif options[option_name].is_a?(type)
- valid = true
+ invalid = type.all?{|t| !val.is_a?(t) }
+ elsif !val.is_a?(type)
+ invalid = true
end
- if valid
- raise SpreadsheetArchitect::Exceptions::IncorrectTypeError option_name
+ if invalid
+ raise SpreadsheetArchitect::Exceptions::InvalidTypeError.new(":#{option_name} option")
end
end
end
- def self.check_options_types(options={})
- self.check_type(options, :spreadsheet_columns, Array)
- self.check_type(options, :instances, Array)
- self.check_type(options, :headers, [TrueClass, FalseClass, Array])
- self.check_type(options, :sheet_name, String)
- self.check_type(options, :header_style, Hash)
- self.check_type(options, :row_style, Hash)
- self.check_type(options, :column_styles, Array)
- self.check_type(options, :range_styles, Array)
- self.check_type(options, :merges, Array)
- self.check_type(options, :borders, Array)
- self.check_type(options, :column_widths, Array)
+ def self.verify_option_types(options)
+ check_option_type(options, :spreadsheet_columns, Proc)
+ check_option_type(options, :data, Array)
+ check_option_type(options, :instances, Array)
+ check_option_type(options, :headers, [TrueClass, Array])
+ check_option_type(options, :header_style, Hash)
+ check_option_type(options, :row_style, Hash)
+ check_option_type(options, :column_styles, Array)
+ check_option_type(options, :range_styles, Array)
+ check_option_type(options, :merges, Array)
+ check_option_type(options, :borders, Array)
+ check_option_type(options, :column_widths, Array)
end
- # only converts the first 2 levels
def self.stringify_keys(hash={})
new_hash = {}
hash.each do |k,v|
if v.is_a?(Hash)
- v.each do |k2,v2|
- new_hash[k2.to_s] = v2
- end
+ new_hash[k.to_s] = self.stringify_keys(v)
else
new_hash[k.to_s] = v
end
end
return new_hash