Module: ActiveMocker::Mock::Queries
Defined Under Namespace
Classes: Find, WhereNotChain
Instance Method Summary collapse
- #all ⇒ Object
-
#average(key) ⇒ Object
Calculates the average value on a given column.
-
#count(column_name = nil) ⇒ Object
Count the records.
-
#delete_all(conditions = nil) ⇒ Object
(also: #destroy_all)
Deletes the records matching
conditions
by instantiating each record and calling itsdelete
method. -
#find(ids) ⇒ Object
Find by id - 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 anActiveRecord::RecordNotFound
error. -
#find_or_create_by(attributes, &block) ⇒ Object
(also: #find_or_create_by!)
Finds the first record with the given attributes, or creates a record with the attributes if one is not found:.
-
#find_or_initialize_by(attributes, &block) ⇒ Object
Like
find_or_create_by
, but callsnew
instead ofcreate
. -
#limit(num) ⇒ Object
Specifies a limit for the number of records to retrieve.
-
#maximum(key) ⇒ Object
Calculates the maximum value on a given column.
-
#minimum(key) ⇒ Object
Calculates the minimum value on a given column.
-
#order(key) ⇒ 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 column.
-
#update(id, attributes) ⇒ Object
Updates an object (or multiple objects) and saves it.
-
#update_all(conditions) ⇒ Object
Updates all records with details given if they match a set of conditions supplied, limits and order can also be supplied.
-
#where(conditions = nil) ⇒ Object
Returns a new relation, which is the result of filtering the current relation according to the conditions in the arguments.
Instance Method Details
#all ⇒ Object
302 303 304 |
# File 'lib/active_mocker/mock/queries.rb', line 302 def all new_relation(to_a || []) end |
#average(key) ⇒ Object
Calculates the average value on a given column. Returns nil
if there’s no row.
PersonMock.average(:age) # => 35.8
264 265 266 267 268 |
# File 'lib/active_mocker/mock/queries.rb', line 264 def average(key) values = values_by_key(key) total = values.inject { |sum, n| sum + n } BigDecimal.new(total) / BigDecimal.new(values.count) end |
#count(column_name = nil) ⇒ Object
Count the records.
PersonMock.count
# => the total count of all people
PersonMock.count(:age)
# => returns the total count of all people whose age is present in database
235 236 237 238 |
# File 'lib/active_mocker/mock/queries.rb', line 235 def count(column_name = nil) return all.size if column_name.nil? where.not(column_name => nil).size end |
#delete_all(conditions = nil) ⇒ Object Also known as: destroy_all
Deletes the records matching conditions
by instantiating each record and calling its delete
method.
Parameters
-
conditions
- A string, array, or hash that specifies which records to destroy. If omitted, all records are destroyed.
Examples
PersonMock.destroy_all(status: "inactive")
PersonMock.where(age: 0..18).destroy_all
If a limit scope is supplied, delete_all
raises an ActiveMocker error:
Post.limit(100).delete_all
# => ActiveMocker::Mock::Error: delete_all doesn't support limit scope
52 53 54 55 56 57 58 59 |
# File 'lib/active_mocker/mock/queries.rb', line 52 def delete_all(conditions=nil) raise ActiveMocker::Mock::Error.new("delete_all doesn't support limit scope") if from_limit? if conditions.nil? to_a.map(&:delete) return to_a.clear end where(conditions).map { |r| r.delete }.count end |
#find(ids) ⇒ Object
Find by id - 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
.
Person.find(1) # returns the object for ID = 1
Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
Person.find([1]) # returns an array for the object with ID = 1
ActiveRecord::RecordNotFound
will be raised if one or more ids are not found.
122 123 124 125 126 127 128 |
# File 'lib/active_mocker/mock/queries.rb', line 122 def find(ids) results = [*ids].map do |id| find_by!(id: id) end return new_relation(results) if ids.class == Array results.first 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
.
Post.find_by name: 'Spartacus', rating: 4
183 184 185 |
# File 'lib/active_mocker/mock/queries.rb', line 183 def find_by(conditions = {}) send(:where, conditions).first end |
#find_by!(conditions = {}) ⇒ Object
Like find_by
, except that if no record is found, raises an ActiveRecord::RecordNotFound
error.
189 190 191 192 193 |
# File 'lib/active_mocker/mock/queries.rb', line 189 def find_by!(conditions={}) result = find_by(conditions) raise RecordNotFound if result.nil? result end |
#find_or_create_by(attributes, &block) ⇒ Object Also known as: find_or_create_by!
Finds the first record with the given attributes, or creates a record with the attributes if one is not found:
# Find the first user named "Penélope" or create a new one.
UserMock.find_or_create_by(first_name: 'Penélope')
# => #<User id: 1, first_name: "Penélope", last_name: nil>
# Find the first user named "Penélope" or create a new one.
# We already have one so the existing record will be returned.
UserMock.find_or_create_by(first_name: 'Penélope')
# => #<User id: 1, first_name: "Penélope", last_name: nil>
This method accepts a block, which is passed down to create
. The last example above can be alternatively written this way:
# Find the first user named "Scarlett" or create a new one with a
# different last name.
User.find_or_create_by(first_name: 'Scarlett') do |user|
user.last_name = 'Johansson'
end
# => #<User id: 2, first_name: "Scarlett", last_name: "Johansson">
217 218 219 |
# File 'lib/active_mocker/mock/queries.rb', line 217 def find_or_create_by(attributes, &block) find_by(attributes) || create(attributes, &block) end |
#find_or_initialize_by(attributes, &block) ⇒ Object
Like find_or_create_by
, but calls new
instead of create
.
224 225 226 |
# File 'lib/active_mocker/mock/queries.rb', line 224 def find_or_initialize_by(attributes, &block) find_by(attributes) || new(attributes, &block) end |
#limit(num) ⇒ Object
Specifies a limit for the number of records to retrieve.
User.limit(10)
243 244 245 246 247 |
# File 'lib/active_mocker/mock/queries.rb', line 243 def limit(num) relation = new_relation(all.take(num)) relation.send(:set_from_limit) relation end |
#maximum(key) ⇒ Object
Calculates the maximum value on a given column. The value is returned with the same data type of the column, or nil
if there’s no row.
Person.maximum(:age) # => 93
282 283 284 |
# File 'lib/active_mocker/mock/queries.rb', line 282 def maximum(key) values_by_key(key).max_by { |i| i } end |
#minimum(key) ⇒ Object
Calculates the minimum value on a given column. The value is returned with the same data type of the column, or nil
if there’s no row.
Person.minimum(:age) # => 7
274 275 276 |
# File 'lib/active_mocker/mock/queries.rb', line 274 def minimum(key) values_by_key(key).min_by { |i| i } end |
#order(key) ⇒ Object
Allows to specify an order attribute:
User.order('name')
User.order(:name)
291 292 293 |
# File 'lib/active_mocker/mock/queries.rb', line 291 def order(key) new_relation(all.sort_by { |item| item.send(key) }) end |
#reverse_order ⇒ Object
Reverse the existing order clause on the relation.
User.order('name').reverse_order
298 299 300 |
# File 'lib/active_mocker/mock/queries.rb', line 298 def reverse_order new_relation(to_a.reverse) end |
#sum(key) ⇒ Object
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.
Person.sum(:age) # => 4562
253 254 255 256 257 258 |
# File 'lib/active_mocker/mock/queries.rb', line 253 def sum(key) values = values_by_key(key) values.inject(0) do |sum, n| sum + (n || 0) end end |
#update(id, attributes) ⇒ Object
Updates an object (or multiple objects) and saves it.
Parameters
-
id
- This should be the id or an array of ids to be updated. -
attributes
- This should be a hash of attributes or an array of hashes.
Examples
# Updates one record
Person.update(15, user_name: 'Samuel', group: 'expert')
# Updates multiple records
people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
Person.update(people.keys, people.values)
166 167 168 169 170 171 172 173 174 |
# File 'lib/active_mocker/mock/queries.rb', line 166 def update(id, attributes) if id.is_a?(Array) id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) } else object = find(id) object.update(attributes) object end end |
#update_all(conditions) ⇒ Object
Updates all records with details given if they match a set of conditions supplied, limits and order can also be supplied.
Parameters
-
updates
- A string, array, or hash.
Examples
# Update all customers with the given attributes
Customer.update_all wants_email: true
# Update all books with 'Rails' in their title
BookMock.where(title: 'Rails').update_all(author: 'David')
# Update all books that match conditions, but limit it to 5 ordered by date
BookMock.where(title: 'Rails').order(:created_at).limit(5).update_all(author: 'David')
147 148 149 |
# File 'lib/active_mocker/mock/queries.rb', line 147 def update_all(conditions) all.each { |i| i.update(conditions) } end |
#where(conditions = nil) ⇒ Object
Returns a new relation, which is the result of filtering the current relation according to the conditions in the arguments.
hash
#where will accept a hash condition, in which the keys are fields and the values are values to be searched for.
Fields can be symbols or strings. Values can be single values, arrays, or ranges.
User.where({ name: "Joe", email: "[email protected]" })
User.where({ name: ["Alice", "Bob"]})
User.where({ created_at: (Time.now.midnight - 1.day)..Time.now.midnight })
In the case of a belongs_to relationship, an association key can be used to specify the model if an ActiveRecord object is used as the value.
= Author.find(1)
# The following queries will be equivalent:
Post.where(author: )
Post.where(author_id: )
This also works with polymorphic belongs_to relationships:
treasure = Treasure.create(name: 'gold coins')
treasure.price_estimates << PriceEstimate.create(price: 125)
# The following queries will be equivalent:
PriceEstimate.where(estimate_of: treasure)
PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: treasure)
no argument
If no argument is passed, #where returns a new instance of WhereChain, that can be chained with #not to return a new relation that negates the where clause.
User.where.not(name: "Jon")
See WhereChain for more details on #not.
105 106 107 108 109 110 |
# File 'lib/active_mocker/mock/queries.rb', line 105 def where(conditions=nil) return WhereNotChain.new(all, method(:new_relation)) if conditions.nil? new_relation(to_a.select do |record| Find.new(record).is_of(conditions) end) end |