Skip to content

Commit 2add1f8

Browse files
raldredezekg
authored andcommitted
Added support for using an associations attribute
1 parent 051da95 commit 2add1f8

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

lib/active_record_distinct_on/distinct_on_query_methods.rb

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
require 'active_record_distinct_on'
2-
32
module ActiveRecordDistinctOn
43
module DistinctOnQueryMethods
54
extend ActiveSupport::Concern
@@ -70,15 +69,26 @@ def build_distinct_on(arel)
7069
end
7170

7271
def distinct_on_arel_columns
73-
arel_attributes = distinct_on_values.map { |field|
74-
if klass.attribute_alias?(field)
75-
arel_table[klass.attribute_alias(field).to_sym]
72+
arel_attributes = distinct_on_values.map do |field|
73+
if field.is_a?(String)
74+
field
75+
elsif field.is_a?(Hash)
76+
assoc = field.keys.first
77+
assoc_klass = klass.reflect_on_association(assoc).klass
78+
assoc_field = field[assoc].to_sym
79+
build_distinct_on_field(assoc_klass, assoc_field)
7680
else
77-
arel_table[field]
81+
build_distinct_on_field(klass, field)
7882
end
79-
}
83+
end
84+
85+
arel_columns(arel_attributes)
86+
end
87+
88+
def build_distinct_on_field(klass, field)
89+
return klass.arel_table[klass.attribute_alias(field).to_sym] if klass.attribute_alias?(field)
8090

81-
arel_columns arel_attributes
91+
klass.arel_table[field]
8292
end
8393
end
8494
end

spec/active_record_distinct_on/distinct_on_query_methods_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,38 @@
3434
end
3535
end
3636

37+
context 'with an associations attribute' do
38+
39+
let(:arel) { subject.joins(:dog_to_toys).distinct_on(*attribute_names).arel }
40+
let(:select_statement) { arel.ast }
41+
let(:set_quantifies) { select_statement.cores.map(&:set_quantifier) }
42+
let(:set_quantifier_attributes) { set_quantifies.flat_map(&:expr) }
43+
44+
context 'as an object' do
45+
let(:attribute_names) { [:id, {dog_to_toys: :created_at}] }
46+
47+
it 'produces arel with a set_quantifier with the relations' do
48+
expect(set_quantifier_attributes.first.relation.name).to eq "dogs"
49+
expect(set_quantifier_attributes.first.name.to_sym).to eq :id
50+
51+
expect(set_quantifier_attributes.second.relation.name).to eq "dog_to_toys"
52+
expect(set_quantifier_attributes.second.name.to_sym).to eq :created_at
53+
end
54+
end
55+
56+
context 'as a string' do
57+
let(:attribute_names) { [:id, "dog_to_toys.created_at"] }
58+
59+
it 'produces arel with a set_quantifier with the relations' do
60+
expect(set_quantifier_attributes.first.relation.name).to eq "dogs"
61+
expect(set_quantifier_attributes.first.name.to_sym).to eq :id
62+
63+
expect(set_quantifier_attributes.second.relation.name).to eq "dog_to_toys"
64+
expect(set_quantifier_attributes.second.name.to_sym).to eq :created_at
65+
end
66+
end
67+
end
68+
3769
context 'when chained' do
3870
it 'behaves the same as having been called once with all of the arguments' do
3971
expect(subject.distinct_on(:a).distinct_on(:b, :c).distinct_on_values).to(

0 commit comments

Comments
 (0)