Movatterモバイル変換


[0]ホーム

URL:


Skip to ContentSkip to Search
Ruby on Rails 8.1.1

Module ActiveRecord::Calculations

v8.1.1

Active Record Calculations

Methods
A
C
I
M
P
S

Instance Public methods

async_average(column_name)Link

Same asaverage, but performs the query asynchronously and returns anActiveRecord::Promise.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 122defasync_average(column_name)async.average(column_name)end

async_count(column_name = nil)Link

Same ascount, but performs the query asynchronously and returns anActiveRecord::Promise.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 108defasync_count(column_name =nil)async.count(column_name)end

async_ids()Link

Same asids, but performs the query asynchronously and returns anActiveRecord::Promise.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 413defasync_idsasync.idsend

async_maximum(column_name)Link

Same asmaximum, but performs the query asynchronously and returns anActiveRecord::Promise.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 152defasync_maximum(column_name)async.maximum(column_name)end

async_minimum(column_name)Link

Same asminimum, but performs the query asynchronously and returns anActiveRecord::Promise.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 137defasync_minimum(column_name)async.minimum(column_name)end

async_pick(*column_names)Link

Same aspick, but performs the query asynchronously and returns anActiveRecord::Promise.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 367defasync_pick(*column_names)async.pick(*column_names)end

async_pluck(*column_names)Link

Same aspluck, but performs the query asynchronously and returns anActiveRecord::Promise.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 338defasync_pluck(*column_names)async.pluck(*column_names)end

async_sum(identity_or_column = nil)Link

Same assum, but performs the query asynchronously and returns anActiveRecord::Promise.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 181defasync_sum(identity_or_column =nil)async.sum(identity_or_column)end

average(column_name)Link

Calculates the average value on a given column. Returnsnil if there’s no row. Seecalculate for examples with options.

Person.average(:age)# => 35.8

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 116defaverage(column_name)calculate(:average,column_name)end

calculate(operation, column_name)Link

This calculates aggregate values in the given column. Methods forcount,sum,average,minimum, andmaximum have been added as shortcuts.

Person.calculate(:count,:all)# The same as Person.countPerson.average(:age)# SELECT AVG(age) FROM people...# Selects the minimum age for any family without any minorsPerson.group(:last_name).having("min(age) > 17").minimum(:age)Person.sum("2 * age")

There are two basic forms of output:

  • Single aggregate value: The single value is type cast toInteger for COUNT,Float for AVG, and the given column’s type for everything else.

  • Grouped values: This returns an ordered hash of the values and groups them. It takes either a column name, or the name of abelongs_to association.

    values = Person.group('last_name').maximum(:age)puts values["Drake"]# => 43drake  = Family.find_by(last_name: 'Drake')values = Person.group(:family).maximum(:age) # Person belongs_to :familyputs values[drake]# => 43values.each do |family, max_age|  ...end

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 216defcalculate(operation,column_name)operation =operation.to_s.downcaseif@nonecaseoperationwhen"count","sum"result =group_values.any??Hash.new:0return@async?Promise::Complete.new(result):resultwhen"average","minimum","maximum"result =group_values.any??Hash.new:nilreturn@async?Promise::Complete.new(result):resultendendifhas_include?(column_name)relation =apply_join_dependencyifoperation=="count"unlessdistinct_value||distinct_select?(column_name||select_for_count)relation.distinct!relation.select_values =Array(model.primary_key||table[Arel.star])end# PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCTrelation.order_values = []ifgroup_values.empty?endrelation.calculate(operation,column_name)elseperform_calculation(operation,column_name)endend

count(column_name = nil)Link

Count the records.

Person.count# => the total count of all peoplePerson.count(:age)# => returns the total count of all people whose age is present in databasePerson.count(:all)# => performs a COUNT(*) (:all is an alias for '*')Person.distinct.count(:age)# => counts the number of different age values

Ifcount is used withRelation#group, it returns aHash whose keys represent the aggregated column, and the values are the respective amounts:

Person.group(:city).count# => { 'Rome' => 5, 'Paris' => 3 }

Ifcount is used withRelation#group for multiple columns, it returns aHash whose keys are an array containing the individual values of each column and the value of each key would be the count.

Article.group(:status,:category).count# =>  {["draft", "business"]=>10, ["draft", "technology"]=>4, ["published", "technology"]=>2}

Ifcount is used withRelation#select, it will count the selected columns:

Person.select(:age).count# => counts the number of different age values

Note: not all validRelation#select expressions are validcount expressions. The specifics differ between databases. In invalid cases, an error from the database is thrown.

When given a block, calls the block with each record in the relation and returns the number of records for which the block returns a truthy value.

Person.count {|person|person.age>21 }# => counts the number of people older that 21

If the relation hasn’t been loaded yet, callingcount with a block will load all records in the relation. If there are a lot of records in the relation, loading all records could result in performance issues.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 94defcount(column_name =nil)ifblock_given?unlesscolumn_name.nil?raiseArgumentError,"Column name argument is not supported when a block is passed."endsuper()elsecalculate(:count,column_name)endend

ids()Link

Returns the base model’s ID’s for the relation using the table’s primary key

Person.ids# SELECT people.id FROM peoplePerson.joins(:company).ids# SELECT people.id FROM people INNER JOIN companies ON companies.id = people.company_id

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 375defidsprimary_key_array =Array(primary_key)ifloaded?result =records.mapdo|record|ifprimary_key_array.one?record._read_attribute(primary_key_array.first)elseprimary_key_array.map {|column|record._read_attribute(column) }endendreturn@async?Promise::Complete.new(result):resultendifhas_include?(primary_key)relation =apply_join_dependency.group(*primary_key_array)returnrelation.idsendcolumns =arel_columns(primary_key_array)relation =spawnrelation.select_values =columnsresult =ifrelation.where_clause.contradiction?ActiveRecord::Result.emptyelseskip_query_cache_if_necessarydomodel.with_connectiondo|c|c.select_all(relation,"#{model.name} Ids",async:@async)endendendresult.then {|result|type_cast_pluck_values(result,columns) }end

maximum(column_name)Link

Calculates the maximum value on a given column. The value is returned with the same data type of the column, ornil if there’s no row. Seecalculate for examples with options.

Person.maximum(:age)# => 93

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 146defmaximum(column_name)calculate(:maximum,column_name)end

minimum(column_name)Link

Calculates the minimum value on a given column. The value is returned with the same data type of the column, ornil if there’s no row. Seecalculate for examples with options.

Person.minimum(:age)# => 7

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 131defminimum(column_name)calculate(:minimum,column_name)end

pick(*column_names)Link

Pick the value(s) from the named column(s) in the current relation. This is short-hand forrelation.limit(1).pluck(*column_names).first, and is primarily useful when you have a relation that’s already narrowed down to a single row.

Just likepluck,pick will only load the actual value, not the entire record object, so it’s also more efficient. The value is, again like with pluck, typecast by the column type.

Person.where(id:1).pick(:name)# SELECT people.name FROM people WHERE id = 1 LIMIT 1# => 'David'Person.where(id:1).pick(:name,:email_address)# SELECT people.name, people.email_address FROM people WHERE id = 1 LIMIT 1# => [ 'David', 'david@loudthinking.com' ]

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 356defpick(*column_names)ifloaded?&&all_attributes?(column_names)result =records.pick(*column_names)return@async?Promise::Complete.new(result):resultendlimit(1).pluck(*column_names).then(&:first)end

pluck(*column_names)Link

Usepluck as a shortcut to select one or more attributes without loading an entire record object per row.

Person.pluck(:name)

instead of

Person.all.map(&:name)

Pluck returns anArray of attribute values type-casted to match the plucked column names, if they can be deduced. Plucking an SQL fragment returnsString values by default.

Person.pluck(:name)# SELECT people.name FROM people# => ['David', 'Jeremy', 'Jose']Person.pluck(:id,:name)# SELECT people.id, people.name FROM people# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]Person.distinct.pluck(:role)# SELECT DISTINCT role FROM people# => ['admin', 'member', 'guest']Person.where(age:21).limit(5).pluck(:id)# SELECT people.id FROM people WHERE people.age = 21 LIMIT 5# => [2, 3]Comment.joins(:person).pluck(:id,person::id)# SELECT comments.id, person.id FROM comments INNER JOIN people person ON person.id = comments.person_id# => [[1, 2], [2, 2]]Comment.joins(:person).pluck(:id,person: [:id,:name])# SELECT comments.id, person.id, person.name FROM comments INNER JOIN people person ON person.id = comments.person_id# => [[1, 2, 'David'], [2, 2, 'David']]Person.pluck(Arel.sql('DATEDIFF(updated_at, created_at)'))# SELECT DATEDIFF(updated_at, created_at) FROM people# => ['0', '27761', '173']

Be aware thatpluck ignores any previous select clauses

Person.select(:name).pluck(:id)# SELECT people.id FROM people

See alsoids.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 295defpluck(*column_names)if@noneif@asyncreturnPromise::Complete.new([])elsereturn []endendifloaded?&&all_attributes?(column_names)result =records.pluck(*column_names)if@asyncreturnPromise::Complete.new(result)elsereturnresultendendifhas_include?(column_names.first)relation =apply_join_dependencyrelation.pluck(*column_names)elsemodel.disallow_raw_sql!(flattened_args(column_names))relation =spawncolumns =relation.arel_columns(column_names)relation.select_values =columnsresult =skip_query_cache_if_necessarydoifwhere_clause.contradiction?&&!possible_aggregation?(column_names)ActiveRecord::Result.empty(async:@async)elsemodel.with_connectiondo|c|c.select_all(relation.arel,"#{model.name} Pluck",async:@async)endendendresult.thendo|result|type_cast_pluck_values(result,columns)endendend

sum(initial_value_or_column = 0, &block)Link

Calculates the sum of values on a given column. The value is returned with the same data type of the column,0 if there’s no row. Seecalculate for examples with options.

Person.sum(:age)# => 4562

When given a block, calls the block with each record in the relation and returns the sum ofinitial_value_or_column plus the block return values:

Person.sum {|person|person.age }# => 4562Person.sum(1000) {|person|person.age }# => 5562

If the relation hasn’t been loaded yet, callingsum with a block will load all records in the relation. If there are a lot of records in the relation, loading all records could result in performance issues.

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 171defsum(initial_value_or_column =0,&block)ifblock_given?map(&block).sum(initial_value_or_column)elsecalculate(:sum,initial_value_or_column)endend

Instance Protected methods

aggregate_column(column_name)Link

Source:show |on GitHub

# File activerecord/lib/active_record/relation/calculations.rb, line 418defaggregate_column(column_name)casecolumn_namewhenArel::Expressionscolumn_namewhen:allArel.starelsearel_column(column_name.to_s)endend

[8]ページ先頭

©2009-2025 Movatter.jp