Module: ActiveRecord::FinderMethods
- Included in:
- Relation
- Defined in:
- lib/active_record/relation/finder_methods.rb
Instance Method Summary collapse
-
#all(*args) ⇒ Object
A convenience wrapper for find(:all, *args).
-
#exists?(id = false) ⇒ Boolean
Returns true if a record exists in the table that matches the
idor conditions given, or false otherwise. -
#find(*args) ⇒ Object
Find operates with four different retrieval approaches:.
-
#first(*args) ⇒ Object
A convenience wrapper for find(:first, *args).
-
#last(*args) ⇒ Object
A convenience wrapper for find(:last, *args).
Instance Method Details
#all(*args) ⇒ Object
A convenience wrapper for find(:all, *args). You can pass in all the same arguments to this method as you can to find(:all).
142 143 144 |
# File 'lib/active_record/relation/finder_methods.rb', line 142 def all(*args) args.any? ? (args.first).to_a : to_a end |
#exists?(id = false) ⇒ Boolean
Returns true if a record exists in the table that matches the id or
conditions given, or false otherwise. The argument can take five forms:
- Integer - Finds the record with this primary key.
- String - Finds the record with a primary key corresponding to this string (such as '5').
- Array - Finds the record that matches these +find+-style conditions (such as ['color = ?', 'red']).
- Hash - Finds the record that matches these +find+-style conditions (such as {:color => 'red'}).
- No args - Returns false if the table is empty, true otherwise.
For more information about specifying conditions as a Hash or Array, see the Conditions section in the introduction to ActiveRecord::Base.
Note: You can't pass in a condition as a string (like name = 'Jamie'), since it would be sanitized and then queried against the primary key column, like id = 'name = 'Jamie''.
Examples
Person.exists?(5) Person.exists?('5') Person.exists?(:name => "David") Person.exists?(['name LIKE ?', "%#query%"]) Person.exists?
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/active_record/relation/finder_methods.rb', line 171 def exists?(id = false) return false if id.nil? id = id.id if ActiveRecord::Base === id join_dependency = construct_join_dependency_for_association_find relation = construct_relation_for_association_find(join_dependency) relation = relation.except(:select).select("1").limit(1) case id when Array, Hash relation = relation.where(id) else relation = relation.where(table[primary_key.name].eq(id)) if id end connection.select_value(relation.to_sql) ? true : false end |
#find(*args) ⇒ Object
Find operates with four different retrieval approaches:
- 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.
- Find first - This will return the first record matched by the options used. These options can either be specific
conditions or merely an order. If no record can be matched,
nilis returned. Use Model.find(:first, *args) or its shortcut Model.first(*args). - Find last - This will return the last record matched by the options used. These options can either be specific
conditions or merely an order. If no record can be matched,
nilis returned. Use Model.find(:last, *args) or its shortcut Model.last(*args). - Find all - This will return all the records matched by the options used. If no records are found, an empty array is returned. Use Model.find(:all, *args) or its shortcut Model.all(*args).
All approaches accept an options hash as their last parameter.
Parameters
- :conditions - An SQL fragment like "administrator = 1", ["user_name = ?", username], or ["user_name = :user_name", { :user_name => user_name }]. See conditions in the intro.
- :order - An SQL fragment like "created_at DESC, name".
- :group - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
- :having - Combined with
:groupthis can be used to filter the records that a GROUP BY returns. Uses the HAVING SQL-clause. - :limit - An integer determining the limit on the number of rows that should be returned.
- :offset - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
- :joins - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed), named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s), or an array containing a mixture of both strings and named associations. If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table's columns. Pass :readonly => false to override.
- :include - Names associations that should be loaded alongside. The symbols named refer to already defined associations. See eager loading under Associations.
- :select - By default, this is "*" as in "SELECT * FROM", but can be changed if you, for example, want to do a join but not include the joined columns. Takes a string with the SELECT SQL fragment (e.g. "id, name").
- :from - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name of a database view).
- :readonly - Mark the returned records read-only so they cannot be saved or updated.
- :lock - An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE". :lock => true gives connection's default exclusive lock, usually "FOR UPDATE".
Examples
find by id
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 Person.where("administrator = 1").order("created_on DESC").find(1)
Note that returned records may not be in the same order as the ids you provide since database rows are unordered. Give an explicit :order to ensure the results are sorted.
Examples
find first
Person.first # returns the first object fetched by SELECT * FROM people Person.where(["user_name = ?", user_name]).first Person.where(["user_name = :u", { :u => user_name }]).first Person.order("created_on DESC").offset(5).first
find last
Person.last # returns the last object fetched by SELECT * FROM people Person.where(["user_name = ?", user_name]).last Person.order("created_on DESC").offset(5).last
find all
Person.all # returns an array of objects for all the rows fetched by SELECT * FROM people Person.where(["category IN (?)", categories]).limit(50).all Person.where({ :friends => ["Bob", "Steve", "Fred"] }).all Person.offset(10).limit(10).all Person.includes([:account, :friends]).all Person.group("category").all
Example for find with a lock: Imagine two concurrent transactions: each will read person.visits == 2, add 1 to it, and save, resulting in two saves of person.visits = 3. By locking the row, the second transaction has to wait until the first is finished; we get the expected person.visits == 4.
Person.transaction do
person = Person.lock(true).find(1)
person.visits += 1
person.save!
end
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/active_record/relation/finder_methods.rb', line 95 def find(*args) return to_a.find { |*block_args| yield(*block_args) } if block_given? = args. if .present? ().find(*args) else case args.first when :first, :last, :all send(args.first) else find_with_ids(*args) end end end |
#first(*args) ⇒ Object
A convenience wrapper for find(:first, *args). You can pass in all the same arguments to this method as you can to find(:first).
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/active_record/relation/finder_methods.rb', line 114 def first(*args) if args.any? if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash)) to_a.first(*args) else (args.first).first end else find_first end end |
#last(*args) ⇒ Object
A convenience wrapper for find(:last, *args). You can pass in all the same arguments to this method as you can to find(:last).
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/active_record/relation/finder_methods.rb', line 128 def last(*args) if args.any? if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash)) to_a.last(*args) else (args.first).last end else find_last end end |