Module: ActiveEnumerable::Queries
- Included in:
- ActiveEnumerable
- Defined in:
- lib/active_enumerable/queries.rb
Instance Method Summary collapse
-
#average(key) ⇒ Object
Calculates the average value on a given attribute.
-
#count(name = nil) ⇒ Object
Count the records.
-
#find(*args) ⇒ ActiveEnumerable, Object
Find by id - Depends on either having an Object#id or HashInteger This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
-
#find_by(conditions = {}) ⇒ Object
Finds the first record matching the specified conditions.
-
#find_by!(conditions = {}) ⇒ Object
Like
find_by, except that if no record is found, raises anActiveEnumerable::RecordNotFounderror. -
#limit(num) ⇒ Object
Specifies a limit for the number of records to retrieve.
-
#maximum(key) ⇒ Object
Calculates the maximum value on a given attribute.
-
#minimum(key) ⇒ Object
Calculates the minimum value on a given attribute.
-
#none ⇒ Object
Returns a chainable relation with zero records.
-
#order(*args) ⇒ Object
Allows to specify an order attribute:.
-
#reverse_order ⇒ Object
Reverse the existing order clause on the relation.
-
#sum(key) ⇒ Object
Calculates the sum of values on a given attribute.
Instance Method Details
#average(key) ⇒ Object
Calculates the average value on a given attribute. Returns nil if there’s no row.
<#ActiveEnumerable>.average(:age) # => 35.8
89 90 91 92 93 94 |
# File 'lib/active_enumerable/queries.rb', line 89 def average(key) values = values_by_key(key) total = values.inject { |sum, n| sum + n } return unless total BigDecimal.new(total) / BigDecimal.new(values.count) end |
#count(name = nil) ⇒ Object
Count the records.
<#ActiveEnumerable>.count
# => the total count of all people
<#ActiveEnumerable>.count(:age)
# => returns the total count of all people whose age is not nil
62 63 64 65 |
# File 'lib/active_enumerable/queries.rb', line 62 def count(name = nil) return to_a.size if name.nil? to_a.reject { |record| Finder.new(record).is_of(name: nil) }.size end |
#find(*args) ⇒ ActiveEnumerable, Object
Find by id - Depends on either having an Object#id or HashInteger This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). If no record can be found for all of the listed ids, then RecordNotFound will be raised. If the primary key is an integer, find by id coerces its arguments using to_i.
<#ActiveEnumerable>.find(1) # returns the object for ID = 1
<#ActiveEnumerable>.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
<#ActiveEnumerable>.find([7, 17]) # returns an array for objects with IDs in (7, 17)
<#ActiveEnumerable>.find([1]) # returns an array for the object with ID = 1
ActiveEnumerable::RecordNotFound will be raised if one or more ids are not found.
19 20 21 22 23 24 25 26 27 28 |
# File 'lib/active_enumerable/queries.rb', line 19 def find(*args) raise RecordNotFound.new("Couldn't find #{self.respond_to?(:name) ? self.name : self.class.name} without an ID") if args.compact.empty? if args.count > 1 || args.first.is_a?(Array) __new_relation__(args.flatten.lazy.map do |id| find_by!(id: id.to_i) end) else find_by!(id: args.first.to_i) end end |
#find_by(conditions = {}) ⇒ Object
Finds the first record matching the specified conditions. There is no implied ordering so if order matters, you should specify it yourself.
If no record is found, returns nil.
<#ActiveEnumerable>.find_by name: 'Spartacus', rating: 4
# @see ActiveEnumerable::Finder#is_of for all usages of conditions.
39 40 41 42 43 |
# File 'lib/active_enumerable/queries.rb', line 39 def find_by(conditions = {}) to_a.detect do |record| Finder.new(record).is_of(conditions) end end |
#find_by!(conditions = {}) ⇒ Object
Like find_by, except that if no record is found, raises an ActiveEnumerable::RecordNotFound error.
47 48 49 50 51 52 53 |
# File 'lib/active_enumerable/queries.rb', line 47 def find_by!(conditions={}) result = find_by(conditions) if result.nil? raise RecordNotFound.new("Couldn't find #{self.name} with '#{conditions.keys.first}'=#{conditions.values.first}") end result end |
#limit(num) ⇒ Object
Specifies a limit for the number of records to retrieve.
<#ActiveEnumerable>.limit(10)
70 71 72 |
# File 'lib/active_enumerable/queries.rb', line 70 def limit(num) __new_relation__(all.take(num)) end |
#maximum(key) ⇒ Object
Calculates the maximum value on a given attribute. The value is returned with the same data type of the attribute, or nil if there’s no row.
<#ActiveEnumerable>.maximum(:age) # => 93
108 109 110 |
# File 'lib/active_enumerable/queries.rb', line 108 def maximum(key) values_by_key(key).max_by { |i| i } end |
#minimum(key) ⇒ Object
Calculates the minimum value on a given attribute. Returns nil if there’s no row.
<#ActiveEnumerable>.minimum(:age) # => 7
100 101 102 |
# File 'lib/active_enumerable/queries.rb', line 100 def minimum(key) values_by_key(key).min_by { |i| i } end |
#none ⇒ Object
Returns a chainable relation with zero records.
Any subsequent condition chained to the returned relation will continue generating an empty relation.
Used in cases where a method or scope could return zero records but the result needs to be chainable.
For example:
@posts = current_user.visible_posts.where(name: params[:name])
# => the visible_posts method is expected to return a chainable Relation
def visible_posts
case role
when 'Country Manager'
<#ActiveEnumerable>.where(country: country)
when 'Reviewer'
<#ActiveEnumerable>.published
when 'Bad User'
<#ActiveEnumerable>.none # It can't be chained if [] is returned.
end
end
157 158 159 |
# File 'lib/active_enumerable/queries.rb', line 157 def none __new_relation__([]) end |
#order(*args) ⇒ Object
Allows to specify an order attribute:
<#ActiveEnumerable>.order('name')
<#ActiveEnumerable>.order(:name)
<#ActiveEnumerable>.order(email: :desc)
<#ActiveEnumerable>.order(:name, email: :desc)
121 122 123 |
# File 'lib/active_enumerable/queries.rb', line 121 def order(*args) __new_relation__(Order.call(args, all)) end |
#reverse_order ⇒ Object
Reverse the existing order clause on the relation.
<#ActiveEnumerable>.order('name').reverse_order
129 130 131 |
# File 'lib/active_enumerable/queries.rb', line 129 def reverse_order __new_relation__(to_a.reverse) end |
#sum(key) ⇒ Object
Calculates the sum of values on a given attribute. The value is returned with the same data type of the attribute, 0 if there’s no row.
<#ActiveEnumerable>.sum(:age) # => 4562
78 79 80 81 82 83 |
# File 'lib/active_enumerable/queries.rb', line 78 def sum(key) values = values_by_key(key) values.inject(0) do |sum, n| sum + (n || 0) end end |