diff --git a/lib/tabulatr/data/data.rb b/lib/tabulatr/data/data.rb index 1763f06..8a46526 100644 --- a/lib/tabulatr/data/data.rb +++ b/lib/tabulatr/data/data.rb @@ -29,7 +29,7 @@ def initialize(relation) @base ||= relation.respond_to?(:klass) ? relation.klass : relation @table_name = @base.table_name @search = self.class.instance_variable_get('@search') || HashWithIndifferentAccess.new - @includes = Set.new() + @includes = Hash.new(Set.new()) @cname = @base.name.downcase @batch_actions = nil @row = self.class.instance_variable_get('@row') @@ -128,14 +128,29 @@ def check_params(params) def join_required_tables(params) if params[:arguments].present? - tt = (params[:arguments].split(",").select{|s| s[':']}.map do |s| - s.split(':').first - end.uniq.map(&:to_sym)) - tt.delete(@table_name.to_sym) - @includes = @includes + tt + tt = params[:arguments].split(",").select{|s| s[':']}.map do |s| + a = s.split(':') + a.shift if a[0].eql?(@table_name) + a.pop + a.map(&:to_sym) + end.uniq + @includes = tt.reject(&:empty?).inject(@includes) do |h1, arr| + h2 = arr.reverse.inject { |a, n| { n => a } } + if h2.is_a?(Hash) + h1.merge(h2) do |key, oldval, newval| + [oldval, newval] + end + else + if not h1.keys.include?(h2) + s = h1.default + h1.default = s.add(h2) + end + h1 + end + end end # @relation = @relation.includes(@includes.map(&:to_sym)).references(@includes.map(&:to_sym)) - @relation = @relation.eager_load(@includes.map(&:to_sym)) + @relation = @relation.eager_load(@includes, @includes.default.map(&:to_sym)) # @relation = @relation.group("#{@table_name}.#{@base.primary_key}") end diff --git a/lib/tabulatr/data/dsl.rb b/lib/tabulatr/data/dsl.rb index de7073f..c5187c8 100644 --- a/lib/tabulatr/data/dsl.rb +++ b/lib/tabulatr/data/dsl.rb @@ -48,7 +48,8 @@ def column(name, opts = {}, &block) def association(assoc, name, opts = {}, &block) @table_columns ||= [] - assoc_klass = main_class.reflect_on_association(assoc.to_sym) + assoc = Array(assoc) + assoc_klass = assoc.reduce(main_class) { |c,a| c.reflect_on_association(a.to_sym).klass } sql_options = determine_sql(opts, assoc_klass.try(:quoted_table_name), name) opts = { sort_sql: sql_options[:sort_sql], @@ -59,7 +60,10 @@ def association(assoc, name, opts = {}, &block) proxy: self, col_options: Tabulatr::ParamsBuilder.new(opts), table_name: assoc, - output: block_given? ? block : ->(record){a=record.send(assoc); a.try(:read_attribute, name) || a.try(name)}) + output: block_given? ? block : lambda do |record| + a = assoc.inject(record) {|cur,nxt| cur.send(nxt)} + a.try(:read_attribute, name) || a.try(name) + end) @table_columns << table_column end diff --git a/lib/tabulatr/data/filtering.rb b/lib/tabulatr/data/filtering.rb index c151e62..7407a96 100644 --- a/lib/tabulatr/data/filtering.rb +++ b/lib/tabulatr/data/filtering.rb @@ -144,7 +144,7 @@ def date_in_between(from, to, column) end def find_column(name) - table_name, method_name = name.split(':').map(&:to_sym) + *table_name, method_name = name.split(':').map(&:to_sym) table_columns.find { |c| c.table_name == table_name && c.name == method_name } || filters.find { |f| f.name.to_sym == name.to_sym } end diff --git a/lib/tabulatr/data/formatting.rb b/lib/tabulatr/data/formatting.rb index 3207bbc..b8f52f6 100644 --- a/lib/tabulatr/data/formatting.rb +++ b/lib/tabulatr/data/formatting.rb @@ -29,8 +29,10 @@ def apply_formats(locals: {}, controller: nil) view.record = record h = HashWithIndifferentAccess.new table_columns.each do |tc| - h[tc.table_name] ||= HashWithIndifferentAccess.new - h[tc.table_name][tc.name] = tc.value_for(record, view) + n = tc.table_name + n = n.join(':') if n.is_a?(Array) + h[n] ||= HashWithIndifferentAccess.new + h[n][tc.name] = tc.value_for(record, view) end h[:_row_config] = format_row(view, @row) h[:id] = record.id diff --git a/lib/tabulatr/data/sorting.rb b/lib/tabulatr/data/sorting.rb index 23b0012..907f760 100644 --- a/lib/tabulatr/data/sorting.rb +++ b/lib/tabulatr/data/sorting.rb @@ -31,9 +31,8 @@ def apply_sorting(sortparam) else splitted = clname.split('.') end - if splitted.count == 2 - assoc_name = splitted[0].to_sym - name = splitted[1].to_sym + if splitted.count >= 2 + *assoc_name, name = splitted.map(&:to_sym) column = table_columns.find{|c| c.table_name == assoc_name && c.name == name} else name = splitted[0].to_sym diff --git a/lib/tabulatr/json_builder.rb b/lib/tabulatr/json_builder.rb index 2b0835f..ccb5646 100644 --- a/lib/tabulatr/json_builder.rb +++ b/lib/tabulatr/json_builder.rb @@ -51,8 +51,8 @@ def self.build_hash_from requested_attributes, id requested_attributes ||= '' requested_attributes.split(',').each do |par| if par.include? ':' - relation, action = par.split(':') - attrs << {action: action, relation: relation} + *relation, action = par.split(':') + attrs << {action: action, relation: relation.join(':')} else id_included = true if par == id attrs << {action: par}