Skip to content

Commit

Permalink
Chained associations
Browse files Browse the repository at this point in the history
This closes metaminded#66
  • Loading branch information
mlt committed May 21, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 2c62b7a commit f3b6c5f
Showing 7 changed files with 57 additions and 26 deletions.
24 changes: 17 additions & 7 deletions lib/tabulatr/data/data.rb
Original file line number Diff line number Diff line change
@@ -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')
@@ -123,14 +123,24 @@ 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|
# assoc1-assoc12-assoc123:column3
a = s.split(':').first.split('-')
a.shift if a[0].eql?(@table_name)
a.map(&:to_sym) # [:assoc1, :assoc12, :assoc123]
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) { |key, oldval, newval| [oldval, newval] }
else
h1.default << h2 if not h1.keys.include?(h2)
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.to_a)
# @relation = @relation.group("#{@table_name}.#{@base.primary_key}")
end

14 changes: 10 additions & 4 deletions lib/tabulatr/data/dsl.rb
Original file line number Diff line number Diff line change
@@ -47,17 +47,23 @@ def column(name, opts = {}, &block)

def association(assoc, name, opts = {}, &block)
@table_columns ||= []
assoc_klass = main_class.reflect_on_association(assoc.to_sym)
unless assoc.is_a?(Array)
assoc = assoc.to_s.split('-').map(&:to_sym)
end
assoc_klass = assoc.reduce(main_class) { |c,a| c.reflect_on_association(a.to_sym).try(:klass) }
sql_options = determine_sql(opts, assoc_klass.try(:quoted_table_name), name)
opts = {
sort_sql: sql_options[:sort_sql],
filter_sql: sql_options[:filter_sql]}.merge(opts)
table_column = Tabulatr::Renderer::Association.from(
name: name,
klass: assoc_klass.try(:klass),
klass: assoc_klass,
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)})
table_name: assoc.join('-').to_sym,
output: block_given? ? block : lambda do |record|
a = assoc.reduce(record) {|cur,nxt| cur.try(:send, nxt)}
a.try(:read_attribute, name) || a.try(name)
end)
@table_columns << table_column
end

3 changes: 2 additions & 1 deletion lib/tabulatr/renderer/association.rb
Original file line number Diff line number Diff line change
@@ -39,7 +39,8 @@ def association?() true end

def principal_value(record, view)
return super if output || block
v = record.send(table_name)
assoc = table_name.to_s.split('-').map(&:to_sym)
v = assoc.reduce(record) { |cur,nxt| cur.try(:send, nxt) }
if v && v.respond_to?(:to_a) && name != :count
v.map(&:"#{name}")
else
1 change: 1 addition & 0 deletions spec/dummy/app/models/vendor.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
class Vendor < ActiveRecord::Base
has_many :products
belongs_to :parent
end
1 change: 1 addition & 0 deletions spec/dummy/app/tabulatr_data/product_tabulatr_data.rb
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ class ProductTabulatrData < Tabulatr::Data
column :active, sortable: false
column :updated_at, filter: :date do "#{record.updated_at.strftime('%H:%M %d.%m.%Y')}" end
association :vendor, :name, filter: :exact
association %i[vendor parent], :name, filter: :exact, sortable: true, header: 'Parent'
association :tags, :title do |r|
"'#{r.tags.map(&:title).map(&:upcase).join(', ')}'"
end
35 changes: 23 additions & 12 deletions spec/dummy/db/schema.rb
Original file line number Diff line number Diff line change
@@ -11,40 +11,51 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20141223164833) do
ActiveRecord::Schema.define(version: 20180519000000) do

create_table "products", force: true do |t|
create_table "parents", force: :cascade do |t|
t.string "name"
t.string "url"
t.boolean "active"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "products", force: :cascade do |t|
t.integer "vendor_id"
t.string "title"
t.decimal "price"
t.boolean "active"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "publish_at"
t.string "type"
t.integer "status", default: 0
end

add_index "products", ["vendor_id"], name: "index_products_on_vendor_id"

create_table "products_tags", id: false, force: true do |t|
create_table "products_tags", id: false, force: :cascade do |t|
t.integer "tag_id"
t.integer "product_id"
end

create_table "tags", force: true do |t|
create_table "tags", force: :cascade do |t|
t.string "title"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "vendors", force: true do |t|
create_table "vendors", force: :cascade do |t|
t.string "name"
t.string "url"
t.boolean "active"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "parent_id"
end

add_index "vendors", ["parent_id"], name: "index_vendors_on_parent_id"

end
5 changes: 3 additions & 2 deletions spec/features/tabulatrs_spec.rb
Original file line number Diff line number Diff line change
@@ -12,8 +12,9 @@
"officia", "deserunt", "mollit", "anim", "est", "laborum"]

before(:each) do
@vendor1 = Vendor.create!(:name => "ven d'or", :active => true)
@vendor2 = Vendor.create!(:name => 'producer', :active => true)
@parent1 = Parent.create!(:name => "ABC", :active => true)
@vendor1 = Vendor.create!(:name => "ven d'or", :active => true, parent: @parent1)
@vendor2 = Vendor.create!(:name => 'producer', :active => true, parent: @parent1)
@tag1 = Tag.create!(:title => 'foo')
@tag2 = Tag.create!(:title => 'bar')
@tag3 = Tag.create!(:title => 'fubar')

0 comments on commit f3b6c5f

Please sign in to comment.