class SvelteOnRails::Lib::SvelteAttributes
def calculate_class(model, attributes, associations, call_stack: 0)
def calculate_class(model, attributes, associations, call_stack: 0) next_stack = call_stack + 1 set_labels(model, attributes, associations) associations.each do |key, value| reflect = model.reflect_on_association(key.to_s) if reflect calculate_class( reflect, value, {}, call_stack: next_stack ) end end if call_stack == 0 @labels end end
def calculate_instance(record, attributes, associations, call_stack: 0, offset: nil, limit: nil)
def calculate_instance(record, attributes, associations, call_stack: 0, offset: nil, limit: nil) next_stack = call_stack + 1 if record.respond_to?(:each) recs2 = if offset || limit if (record.is_a?(ActiveRecord::Relation) || record.is_a?(ActiveRecord::Associations::CollectionProxy) rescue false) _recs = (offset ? record.offset(offset) : record) (limit ? _recs.limit(limit) : _recs) elsif record.respond_to?(:drop) && record.respond_to?(:take) # that might be a array _recs = offset ? record.drop(offset) : record limit ? _recs.take(limit) : _recs else raise "[svelte-on-rails:to_svelte] unknown class for records: #{record}" end else record end # set_labels(record.first, attributes) values = recs2.map do |rec| calculate_instance(rec, attributes, associations, call_stack: next_stack) end else # we have a single record values = {} set_labels(record, attributes, associations) attributes.each do |attr| raise 'Invalid attribute' unless [Symbol, String].include?(attr.class) raise "[svelte-on-rails:to_svelte] #{record.class} does not respond to: #{attr}" unless record.respond_to?(attr) _key = attr.to_s values[_key] = record.send(_key) end associations.each do |key, val| # we have associations val.each do |_key| next if ['offset', 'limit'].include?(_key.to_s) raise "[svelte-on-rails:to_svelte] #{record.class} does not respond to: #{key}" unless record.respond_to?(key) _offset, _limit, _value = extract_limit(val) _key = key.to_s # inspect association and set_labels reflect = record.class.reflect_on_association(_key) raise "invalid association: #{_key}" unless reflect set_labels(reflect, val) # values recs = record.send(_key) if recs.present? if recs.respond_to?(:each) values[_key] = calculate_instance( recs, val.reject{|v|v.is_a?(Hash)}, {}, call_stack: next_stack, offset: _offset, limit: _limit ) else values[_key] = calculate_instance( recs, val, {}, call_stack: next_stack ) end end end end end if call_stack >= 1 values else [ @labels, values ] end end
def calculate_relation(relation, attributes, associations)
def calculate_relation(relation, attributes, associations) set_labels(relation.klass, attributes) r = relation.map do |rec| calculate_instance(rec, attributes, associations, call_stack: 1) end @labels.merge({ relation.klass.to_s.underscore.pluralize => r }) end
def extract_limit(attributes)
def extract_limit(attributes) _hash_args = attributes.grep(Hash).first.dup attr, lim = if _hash_args.present? hash_args = _hash_args.transform_keys { |key| key.to_s } # multiple arrays is not possible hash_remainder = hash_args.reject { |key, _| %w[offset limit].include?(key.to_s) } _attr = attributes.reject { |item| item.is_a?(Hash) } [ if hash_remainder.any? _attr + [hash_remainder] else _attr end, hash_args ] else [ attributes, {} ] end [ lim['offset'], lim['limit'], attr ] end
def initialize
def initialize @labels = {} end
def set_labels(record, keys, assoc = {})
def set_labels(record, keys, assoc = {}) _keys = keys.reject { |element| element.is_a?(Hash) } + assoc.keys _keys.each do |attr| unless attr.respond_to?(:each) obj = if record.respond_to?(:human_attribute_name) record elsif record.class.respond_to?(:human_attribute_name) record.class end next unless obj @labels["#{obj.to_s.underscore}_labels"] ||= {} @labels["#{obj.to_s.underscore}_labels"][attr.to_s] ||= obj.human_attribute_name(attr) end end end