Module: CoreExtensions::ActiveRecord::Relation
- Defined in:
- lib/core_extensions/active_record/relation.rb
Class Method Summary collapse
Instance Method Summary collapse
-
#final(final = true) ⇒ Object
When FINAL is specified, ClickHouse fully merges the data before returning the result and thus performs all data transformations that happen during merges for the given table engine.
- #final!(final = true) ⇒ Object
- #final_value ⇒ Object
- #final_value=(value) ⇒ Object
-
#group_by_grouping_sets(*grouping_sets) ⇒ Object
GROUPING SETS allows you to specify multiple groupings in the GROUP BY clause.
-
#group_by_grouping_sets!(*grouping_sets) ⇒ Object
:nodoc:.
-
#limit_by(*opts) ⇒ Object
The LIMIT BY clause permit to improve deduplication based on a unique key, it has better performances than the GROUP BY clause.
- #limit_by!(*opts) ⇒ Object
- #reverse_order! ⇒ Object
-
#settings(**opts) ⇒ Object
Specify settings to be used for this single query.
- #settings!(**opts) ⇒ Object
- #settings_values ⇒ Object
- #settings_values=(value) ⇒ Object
-
#using(*opts) ⇒ Object
The USING clause specifies one or more columns to join, which establishes the equality of these columns.
- #using!(*opts) ⇒ Object
-
#window(name, **opts) ⇒ Object
Windows functions let you perform calculations across a set of rows that are related to the current row.
- #window!(name, **opts) ⇒ Object
Class Method Details
.prepended(base) ⇒ Object
5 6 7 |
# File 'lib/core_extensions/active_record/relation.rb', line 5 def self.prepended(base) base::VALID_UNSCOPING_VALUES << :final << :settings end |
Instance Method Details
#final(final = true) ⇒ Object
When FINAL is specified, ClickHouse fully merges the data before returning the result and thus performs all data transformations that happen during merges for the given table engine. For example:
users = User.final.all
# SELECT users.* FROM users FINAL
An ActiveRecord::ActiveRecordError
will be raised if database not ClickHouse.
69 70 71 |
# File 'lib/core_extensions/active_record/relation.rb', line 69 def final(final = true) spawn.final!(final) end |
#final!(final = true) ⇒ Object
74 75 76 77 78 |
# File 'lib/core_extensions/active_record/relation.rb', line 74 def final!(final = true) check_command!('FINAL') self.final_value = final self end |
#final_value ⇒ Object
89 90 91 |
# File 'lib/core_extensions/active_record/relation.rb', line 89 def final_value @values.fetch(:final, nil) end |
#final_value=(value) ⇒ Object
80 81 82 83 84 85 86 87 |
# File 'lib/core_extensions/active_record/relation.rb', line 80 def final_value=(value) if ::ActiveRecord::version >= Gem::Version.new('7.2') assert_modifiable! else assert_mutability! end @values[:final] = value end |
#group_by_grouping_sets(*grouping_sets) ⇒ Object
GROUPING SETS allows you to specify multiple groupings in the GROUP BY clause. Whereas GROUP BY CUBE generates all possible groupings, GROUP BY GROUPING SETS generates only the specified groupings. For example:
users = User.group_by_grouping_sets([], [:name], [:name, :age]).select(:name, :age, 'count(*)')
# SELECT name, age, count(*) FROM users GROUP BY GROUPING SETS ( (), (name), (name, age) )
which is generally equivalent to:
# SELECT NULL, NULL, count(*) FROM users
# UNION ALL
# SELECT name, NULL, count(*) FROM users GROUP BY name
# UNION ALL
# SELECT name, age, count(*) FROM users GROUP BY name, age
Raises ArgumentError
if no grouping sets are specified are provided.
108 109 110 111 112 |
# File 'lib/core_extensions/active_record/relation.rb', line 108 def group_by_grouping_sets(*grouping_sets) raise ArgumentError, 'The method .group_by_grouping_sets() must contain arguments.' if grouping_sets.blank? spawn.group_by_grouping_sets!(*grouping_sets) end |
#group_by_grouping_sets!(*grouping_sets) ⇒ Object
:nodoc:
114 115 116 117 118 |
# File 'lib/core_extensions/active_record/relation.rb', line 114 def group_by_grouping_sets!(*grouping_sets) # :nodoc: grouping_sets = grouping_sets.map { |set| arel_columns(set) } self.group_values += [::Arel::Nodes::GroupingSets.new(grouping_sets)] self end |
#limit_by(*opts) ⇒ Object
The LIMIT BY clause permit to improve deduplication based on a unique key, it has better performances than the GROUP BY clause
users = User.limit_by(1, id)
# SELECT users.* FROM users LIMIT 1 BY id
An ActiveRecord::ActiveRecordError
will be reaised if database is not Clickhouse.
162 163 164 |
# File 'lib/core_extensions/active_record/relation.rb', line 162 def limit_by(*opts) spawn.limit_by!(*opts) end |
#limit_by!(*opts) ⇒ Object
167 168 169 170 |
# File 'lib/core_extensions/active_record/relation.rb', line 167 def limit_by!(*opts) @values[:limit_by] = *opts self end |
#reverse_order! ⇒ Object
9 10 11 12 13 14 15 16 17 |
# File 'lib/core_extensions/active_record/relation.rb', line 9 def reverse_order! return super unless connection.is_a?(::ActiveRecord::ConnectionAdapters::ClickhouseAdapter) orders = order_values.uniq.reject(&:blank?) return super unless orders.empty? && !primary_key self.order_values = (column_names & %w[date created_at]).map { |c| arel_table[c].desc } self end |
#settings(**opts) ⇒ Object
Specify settings to be used for this single query. For example:
users = User.settings(use_skip_indexes: true).where(name: 'John')
# SELECT "users".* FROM "users"
# WHERE "users"."name" = 'John'
# SETTINGS use_skip_indexes = 1
36 37 38 |
# File 'lib/core_extensions/active_record/relation.rb', line 36 def settings(**opts) spawn.settings!(**opts) end |
#settings!(**opts) ⇒ Object
41 42 43 44 45 |
# File 'lib/core_extensions/active_record/relation.rb', line 41 def settings!(**opts) check_command!('SETTINGS') self.settings_values = settings_values.merge opts self end |
#settings_values ⇒ Object
47 48 49 |
# File 'lib/core_extensions/active_record/relation.rb', line 47 def settings_values @values.fetch(:settings, ::ActiveRecord::QueryMethods::FROZEN_EMPTY_HASH) end |
#settings_values=(value) ⇒ Object
51 52 53 54 55 56 57 58 |
# File 'lib/core_extensions/active_record/relation.rb', line 51 def settings_values=(value) if ::ActiveRecord::version >= Gem::Version.new('7.2') assert_modifiable! else assert_mutability! end @values[:settings] = value end |
#using(*opts) ⇒ Object
The USING clause specifies one or more columns to join, which establishes the equality of these columns. For example:
users = User.joins(:joins).using(:event_name, :date)
# SELECT users.* FROM users INNER JOIN joins USING event_name,date
An ActiveRecord::ActiveRecordError
will be raised if database not ClickHouse.
127 128 129 |
# File 'lib/core_extensions/active_record/relation.rb', line 127 def using(*opts) spawn.using!(*opts) end |
#using!(*opts) ⇒ Object
132 133 134 135 |
# File 'lib/core_extensions/active_record/relation.rb', line 132 def using!(*opts) @values[:using] = opts self end |
#window(name, **opts) ⇒ Object
Windows functions let you perform calculations across a set of rows that are related to the current row. For example:
users = User.window('x', order: 'date', partition: 'name', rows: 'UNBOUNDED PRECEDING').select('sum(value) OVER x')
# SELECT sum(value) OVER x FROM users WINDOW x AS (PARTITION BY name ORDER BY date ROWS UNBOUNDED PRECEDING)
144 145 146 |
# File 'lib/core_extensions/active_record/relation.rb', line 144 def window(name, **opts) spawn.window!(name, **opts) end |
#window!(name, **opts) ⇒ Object
148 149 150 151 152 |
# File 'lib/core_extensions/active_record/relation.rb', line 148 def window!(name, **opts) @values[:windows] = [] unless @values[:windows] @values[:windows] << [name, opts] self end |