- 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.
async_count(column_name = nil)Link
Same ascount, but performs the query asynchronously and returns anActiveRecord::Promise.
async_ids()Link
Same asids, but performs the query asynchronously and returns anActiveRecord::Promise.
async_maximum(column_name)Link
Same asmaximum, but performs the query asynchronously and returns anActiveRecord::Promise.
async_minimum(column_name)Link
Same asminimum, but performs the query asynchronously and returns anActiveRecord::Promise.
async_pick(*column_names)Link
Same aspick, but performs the query asynchronously and returns anActiveRecord::Promise.
async_pluck(*column_names)Link
Same aspluck, but performs the query asynchronously and returns anActiveRecord::Promise.
async_sum(identity_or_column = nil)Link
Same assum, but performs the query asynchronously and returns anActiveRecord::Promise.
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
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 to
Integerfor COUNT,Floatfor 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
# 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.
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
# 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
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
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' ]
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.
# 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.