Module: ActiveRecordDistinctOn::DistinctOnQueryMethods

Extended by:
ActiveSupport::Concern
Defined in:
lib/active_record_distinct_on/distinct_on_query_methods.rb

Constant Summary collapse

FROZEN_EMPTY_ARRAY =
[].freeze

Instance Method Summary collapse

Instance Method Details

#count(column_name = nil) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/active_record_distinct_on/distinct_on_query_methods.rb', line 35

def count(column_name = nil)
  if distinct_on_values.empty?
    super
  else
    if column_name && column_name != :all
      raise ArgumentError,
            "Cannot use column_name to .count for scopes that already specify `distinct_on` values"
    end

    # See https://github.com/rails/rails/pull/41622#issuecomment-1303078730
    # We need to convert SQL that looks like "SELECT DISTINCT ON ( "dogs"."id" ) COUNT(*) FROM "dogs" ..."
    # into SQL that looks like "SELECT COUNT(DISTINCT ( "dogs"."id" )) FROM "dogs" ...".
    scope = spawn
    scope.distinct_on_values = FROZEN_EMPTY_ARRAY

    column_names = distinct_on_arel_columns.map do |col|
      "\"#{col.relation.name}\".\"#{col.name}\""
    end

    scope.count("distinct #{column_names.join(', ')}")
  end
end

#distinct_on(*fields) ⇒ Object

Raises:

  • (ArgumentError)


24
25
26
27
# File 'lib/active_record_distinct_on/distinct_on_query_methods.rb', line 24

def distinct_on(*fields)
  raise ArgumentError, 'Call this with at least one field' if fields.empty?
  spawn.distinct_on!(*fields)
end

#distinct_on!(*fields) ⇒ Object



29
30
31
32
33
# File 'lib/active_record_distinct_on/distinct_on_query_methods.rb', line 29

def distinct_on!(*fields)
  fields.flatten!
  self.distinct_on_values += fields
  self
end

#distinct_on_valuesObject



16
17
18
# File 'lib/active_record_distinct_on/distinct_on_query_methods.rb', line 16

def distinct_on_values
  @values[:distinct_on] || FROZEN_EMPTY_ARRAY
end

#distinct_on_values=(values) ⇒ Object



20
21
22
# File 'lib/active_record_distinct_on/distinct_on_query_methods.rb', line 20

def distinct_on_values=(values)
  @values[:distinct_on] = values
end