rails / rails

Ruby on Rails

This URL has Read+Write access

af0d1fa8 » josevalim 2009-10-07 Update Orchestra instrument... 1 require 'benchmark'
db045dbb » dhh 2004-11-23 Initial 2 require 'yaml'
aabf9093 » jeremy 2005-11-02 Correct reader method gener... 3 require 'set'
a15e02d4 » josevalim 2009-10-09 Unify benchmark APIs. 4 require 'active_support/benchmarkable'
f5d720fb » jeremy 2009-04-22 Opt in to Dependencies 5 require 'active_support/dependencies'
5f222c52 » jeremy 2009-05-20 Remove 'core' fluff. Hookab... 6 require 'active_support/time'
e8550ee0 » jeremy 2009-05-13 Cherry-pick core extensions 7 require 'active_support/core_ext/class/attribute_accessors'
8 require 'active_support/core_ext/class/delegating_attributes'
9 require 'active_support/core_ext/class/inheritable_attributes'
10 require 'active_support/core_ext/array/extract_options'
11 require 'active_support/core_ext/hash/deep_merge'
12 require 'active_support/core_ext/hash/indifferent_access'
13 require 'active_support/core_ext/hash/slice'
14 require 'active_support/core_ext/string/behavior'
a69b28a8 » jeremy 2009-05-18 Missing 1.8.7 backport exte... 15 require 'active_support/core_ext/symbol'
d3296539 » fxn 2009-06-12 uses Object#metaclass and O... 16 require 'active_support/core_ext/object/metaclass'
db045dbb » dhh 2004-11-23 Initial 17
18 module ActiveRecord #:nodoc:
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 19 # Generic Active Record exception class.
73673256 » jeremy 2007-12-09 Document Active Record exce... 20 class ActiveRecordError < StandardError
db045dbb » dhh 2004-11-23 Initial 21 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 22
0432d151 » lifo 2008-07-16 Merge with docrails. Comment 23 # Raised when the single-table inheritance mechanism fails to locate the subclass
73673256 » jeremy 2007-12-09 Document Active Record exce... 24 # (for example due to improper usage of column that +inheritance_column+ points to).
605bc775 » dhh 2004-12-14 Added a better exception fo... 25 class SubclassNotFound < ActiveRecordError #:nodoc:
26 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 27
64092de2 » fxn 2008-05-02 Improve documentation cover... 28 # Raised when an object assigned to an association has an incorrect type.
73673256 » jeremy 2007-12-09 Document Active Record exce... 29 #
64092de2 » fxn 2008-05-02 Improve documentation cover... 30 # class Ticket < ActiveRecord::Base
31 # has_many :patches
32 # end
73673256 » jeremy 2007-12-09 Document Active Record exce... 33 #
64092de2 » fxn 2008-05-02 Improve documentation cover... 34 # class Patch < ActiveRecord::Base
35 # belongs_to :ticket
36 # end
73673256 » jeremy 2007-12-09 Document Active Record exce... 37 #
64092de2 » fxn 2008-05-02 Improve documentation cover... 38 # # Comments are not patches, this assignment raises AssociationTypeMismatch.
39 # @ticket.patches << Comment.new(:content => "Please attach tests to your patch.")
73673256 » jeremy 2007-12-09 Document Active Record exce... 40 class AssociationTypeMismatch < ActiveRecordError
db045dbb » dhh 2004-11-23 Initial 41 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 42
43 # Raised when unserialized object's type mismatches one specified for serializable field.
44 class SerializationTypeMismatch < ActiveRecordError
db045dbb » dhh 2004-11-23 Initial 45 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 46
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 47 # Raised when adapter not specified on connection (or configuration file <tt>config/database.yml</tt> misses adapter field).
73673256 » jeremy 2007-12-09 Document Active Record exce... 48 class AdapterNotSpecified < ActiveRecordError
db045dbb » dhh 2004-11-23 Initial 49 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 50
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 51 # Raised when Active Record cannot find database adapter specified in <tt>config/database.yml</tt> or programmatically.
73673256 » jeremy 2007-12-09 Document Active Record exce... 52 class AdapterNotFound < ActiveRecordError
db045dbb » dhh 2004-11-23 Initial 53 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 54
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 55 # Raised when connection to the database could not been established (for example when <tt>connection=</tt> is given a nil object).
73673256 » jeremy 2007-12-09 Document Active Record exce... 56 class ConnectionNotEstablished < ActiveRecordError
db045dbb » dhh 2004-11-23 Initial 57 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 58
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 59 # Raised when Active Record cannot find record by given id or set of ids.
73673256 » jeremy 2007-12-09 Document Active Record exce... 60 class RecordNotFound < ActiveRecordError
db045dbb » dhh 2004-11-23 Initial 61 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 62
63 # Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be
64 # saved because record is invalid.
65 class RecordNotSaved < ActiveRecordError
4c7555ae » dhh 2006-02-28 Fixed that Base.save should... 66 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 67
68 # Raised when SQL statement cannot be executed by the database (for example, it's often the case for MySQL when Ruby driver used is too old).
69 class StatementInvalid < ActiveRecordError
db045dbb » dhh 2004-11-23 Initial 70 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 71
b5dfdc71 » NZKoz 2009-06-25 Make sure the wrapped excep... 72 # Parent class for all specific exceptions which wrap database driver exceptions
73 # provides access to the original exception also.
74 class WrappedDatabaseException < StatementInvalid
75 attr_reader :original_exception
76
77 def initialize(message, original_exception)
78 super(message)
79 @original_exception, = original_exception
80 end
81 end
82
53a3eaa8 » mschuerig 2009-04-04 Translate adapter errors th... 83 # Raised when a record cannot be inserted because it would violate a uniqueness constraint.
b5dfdc71 » NZKoz 2009-06-25 Make sure the wrapped excep... 84 class RecordNotUnique < WrappedDatabaseException
53a3eaa8 » mschuerig 2009-04-04 Translate adapter errors th... 85 end
86
00a5fd3d » mschuerig 2009-04-04 Translate foreign key viola... 87 # Raised when a record cannot be inserted or updated because it references a non-existent record.
b5dfdc71 » NZKoz 2009-06-25 Make sure the wrapped excep... 88 class InvalidForeignKey < WrappedDatabaseException
00a5fd3d » mschuerig 2009-04-04 Translate foreign key viola... 89 end
90
64092de2 » fxn 2008-05-02 Improve documentation cover... 91 # Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
73673256 » jeremy 2007-12-09 Document Active Record exce... 92 # does not match number of expected variables.
93 #
64092de2 » fxn 2008-05-02 Improve documentation cover... 94 # For example, in
73673256 » jeremy 2007-12-09 Document Active Record exce... 95 #
64092de2 » fxn 2008-05-02 Improve documentation cover... 96 # Location.find :all, :conditions => ["lat = ? AND lng = ?", 53.7362]
73673256 » jeremy 2007-12-09 Document Active Record exce... 97 #
64092de2 » fxn 2008-05-02 Improve documentation cover... 98 # two placeholders are given but only one variable to fill them.
73673256 » jeremy 2007-12-09 Document Active Record exce... 99 class PreparedStatementInvalid < ActiveRecordError
554597d6 » dhh 2004-12-08 Added named bind-style vari... 100 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 101
102 # Raised on attempt to save stale record. Record is stale when it's being saved in another query after
103 # instantiation, for example, when two users edit the same wiki page and one starts editing and saves
104 # the page before the other.
105 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 106 # Read more about optimistic locking in ActiveRecord::Locking module RDoc.
73673256 » jeremy 2007-12-09 Document Active Record exce... 107 class StaleObjectError < ActiveRecordError
fbf9281f » dhh 2004-12-31 Added automated optimistic ... 108 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 109
110 # Raised when association is being configured improperly or
111 # user tries to use offset and limit together with has_many or has_and_belongs_to_many associations.
112 class ConfigurationError < ActiveRecordError
5b9b904f » dhh 2005-07-10 Added support for limit and... 113 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 114
115 # Raised on attempt to update record that is instantiated as read only.
116 class ReadOnlyRecord < ActiveRecordError
64fcb752 » jeremy 2005-10-14 r3618@sedna: jeremy | 200... 117 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 118
6e754551 » lifo 2008-07-28 Merge docrails changes 119 # ActiveRecord::Transactions::ClassMethods.transaction uses this exception
120 # to distinguish a deliberate rollback from other exceptional situations.
121 # Normally, raising an exception will cause the +transaction+ method to rollback
122 # the database transaction *and* pass on the exception. But if you raise an
123 # ActiveRecord::Rollback exception, then the database transaction will be rolled back,
124 # without passing on the exception.
125 #
126 # For example, you could do this in your controller to rollback a transaction:
127 #
128 # class BooksController < ActionController::Base
129 # def create
130 # Book.transaction do
131 # book = Book.new(params[:book])
132 # book.save!
133 # if today_is_friday?
134 # # The system must fail on Friday so that our support department
135 # # won't be out of job. We silently rollback this transaction
136 # # without telling the user.
137 # raise ActiveRecord::Rollback, "Call tech support!"
138 # end
139 # end
140 # # ActiveRecord::Rollback is the only exception that won't be passed on
141 # # by ActiveRecord::Base.transaction, so this line will still be reached
142 # # even on Friday.
143 # redirect_to root_url
144 # end
145 # end
73673256 » jeremy 2007-12-09 Document Active Record exce... 146 class Rollback < ActiveRecordError
5b2e8b1e » technoweenie 2007-10-05 Fix that ActiveRecord would... 147 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 148
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 149 # Raised when attribute has a name reserved by Active Record (when attribute has name of one of Active Record instance methods).
73673256 » jeremy 2007-12-09 Document Active Record exce... 150 class DangerousAttributeError < ActiveRecordError
ebbe4fb0 » NZKoz 2007-05-17 Replace the transaction {|t... 151 end
84a14f26 » jeremy 2007-10-07 Raise ProtectedAttributeAss... 152
4f687529 » jeremy 2008-09-08 Revert "Revert "Raise Unkno... 153 # Raised when unknown attributes are supplied via mass assignment.
154 class UnknownAttributeError < NoMethodError
155 end
156
0432d151 » lifo 2008-07-16 Merge with docrails. Comment 157 # Raised when an error occurred while doing a mass assignment to an attribute through the
dc4eec11 » lifo 2008-05-09 Merge docrails: 158 # <tt>attributes=</tt> method. The exception has an +attribute+ property that is the name of the
159 # offending attribute.
160 class AttributeAssignmentError < ActiveRecordError
d2fefbe9 » dhh 2005-03-06 Added MultiparameterAssignm... 161 attr_reader :exception, :attribute
162 def initialize(message, exception, attribute)
163 @exception = exception
164 @attribute = attribute
165 @message = message
166 end
167 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 168
dc4eec11 » lifo 2008-05-09 Merge docrails: 169 # Raised when there are multiple errors while doing a mass assignment through the +attributes+
170 # method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
171 # objects, each corresponding to the error while assigning to an attribute.
172 class MultiparameterAssignmentErrors < ActiveRecordError
d2fefbe9 » dhh 2005-03-06 Added MultiparameterAssignm... 173 attr_reader :errors
174 def initialize(errors)
175 @errors = errors
176 end
177 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 178
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 179 # Active Record objects don't specify their attributes directly, but rather infer them from the table definition with
db045dbb » dhh 2004-11-23 Initial 180 # which they're linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change
181 # is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 182 # database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
183 #
db045dbb » dhh 2004-11-23 Initial 184 # See the mapping rules in table_name and the full example in link:files/README.html for more insight.
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 185 #
db045dbb » dhh 2004-11-23 Initial 186 # == Creation
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 187 #
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 188 # Active Records accept constructor parameters either in a hash or as a block. The hash method is especially useful when
7143d801 » Marcel Molina 2007-11-07 Smattering of grammatical f... 189 # you're receiving the data from somewhere else, like an HTTP request. It works like this:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 190 #
0591c53e » dhh 2005-04-17 Made the dynamic finders us... 191 # user = User.new(:name => "David", :occupation => "Code Artist")
db045dbb » dhh 2004-11-23 Initial 192 # user.name # => "David"
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 193 #
db045dbb » dhh 2004-11-23 Initial 194 # You can also use block initialization:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 195 #
db045dbb » dhh 2004-11-23 Initial 196 # user = User.new do |u|
197 # u.name = "David"
198 # u.occupation = "Code Artist"
199 # end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 200 #
db045dbb » dhh 2004-11-23 Initial 201 # And of course you can just create a bare object and specify the attributes after the fact:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 202 #
db045dbb » dhh 2004-11-23 Initial 203 # user = User.new
204 # user.name = "David"
205 # user.occupation = "Code Artist"
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 206 #
db045dbb » dhh 2004-11-23 Initial 207 # == Conditions
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 208 #
c5ec16e5 » dhh 2006-06-03 Added simple hash condition... 209 # Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
db045dbb » dhh 2004-11-23 Initial 210 # The array form is to be used when the condition input is tainted and requires sanitization. The string form can
c5ec16e5 » dhh 2006-06-03 Added simple hash condition... 211 # be used for statements that don't involve tainted data. The hash form works much like the array form, except
28767075 » jeremy 2007-01-10 Pass a range in :conditions... 212 # only equality and range is possible. Examples:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 213 #
48052d70 » jeremy 2006-06-02 to_xml fixes, features, and... 214 # class User < ActiveRecord::Base
db045dbb » dhh 2004-11-23 Initial 215 # def self.authenticate_unsafely(user_name, password)
3dfa56cc » dhh 2005-06-26 Updated all references to t... 216 # find(:first, :conditions => "user_name = '#{user_name}' AND password = '#{password}'")
db045dbb » dhh 2004-11-23 Initial 217 # end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 218 #
db045dbb » dhh 2004-11-23 Initial 219 # def self.authenticate_safely(user_name, password)
3dfa56cc » dhh 2005-06-26 Updated all references to t... 220 # find(:first, :conditions => [ "user_name = ? AND password = ?", user_name, password ])
db045dbb » dhh 2004-11-23 Initial 221 # end
c5ec16e5 » dhh 2006-06-03 Added simple hash condition... 222 #
223 # def self.authenticate_safely_simply(user_name, password)
224 # find(:first, :conditions => { :user_name => user_name, :password => password })
225 # end
db045dbb » dhh 2004-11-23 Initial 226 # end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 227 #
2575b3b0 » dhh 2004-12-06 Added extra words of cautio... 228 # The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query and is thus susceptible to SQL-injection
7143d801 » Marcel Molina 2007-11-07 Smattering of grammatical f... 229 # attacks if the <tt>user_name</tt> and +password+ parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
73673256 » jeremy 2007-12-09 Document Active Record exce... 230 # <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+ before inserting them in the query,
c5ec16e5 » dhh 2006-06-03 Added simple hash condition... 231 # which will ensure that an attacker can't escape the query and fake the login (or worse).
2575b3b0 » dhh 2004-12-06 Added extra words of cautio... 232 #
5cd38ca2 » dhh 2005-03-27 Added documentation about n... 233 # When using multiple parameters in the conditions, it can easily become hard to read exactly what the fourth or fifth
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 234 # question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That's done by replacing
5cd38ca2 » dhh 2005-03-27 Added documentation about n... 235 # the question marks with symbols and supplying a hash with values for the matching symbol keys:
236 #
a7e6e009 » Marcel Molina 2007-12-05 Documentation for find inco... 237 # Company.find(:first, :conditions => [
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 238 # "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
5cd38ca2 » dhh 2005-03-27 Added documentation about n... 239 # { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
240 # ])
241 #
c5ec16e5 » dhh 2006-06-03 Added simple hash condition... 242 # Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND
243 # operator. For instance:
244 #
245 # Student.find(:all, :conditions => { :first_name => "Harvey", :status => 1 })
246 # Student.find(:all, :conditions => params[:student])
247 #
28767075 » jeremy 2007-01-10 Pass a range in :conditions... 248 # A range may be used in the hash to use the SQL BETWEEN operator:
249 #
250 # Student.find(:all, :conditions => { :grade => 9..12 })
c5ec16e5 » dhh 2006-06-03 Added simple hash condition... 251 #
aa4af60a » lifo 2008-04-04 Improve documentation. 252 # An array may be used in the hash to use the SQL IN operator:
253 #
254 # Student.find(:all, :conditions => { :grade => [9,11,12] })
255 #
e033b5d0 » lifo 2009-07-25 Merge docrails 256 # When joining tables, nested hashes or keys written in the form 'table_name.column_name' can be used to qualify the table name of a
257 # particular condition. For instance:
258 #
259 # Student.find(:all, :conditions => { :schools => { :type => 'public' }}, :joins => :schools)
260 # Student.find(:all, :conditions => { 'schools.type' => 'public' }, :joins => :schools)
261 #
db045dbb » dhh 2004-11-23 Initial 262 # == Overwriting default accessors
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 263 #
7143d801 » Marcel Molina 2007-11-07 Smattering of grammatical f... 264 # All column values are automatically available through basic accessors on the Active Record object, but sometimes you
265 # want to specialize this behavior. This can be done by overwriting the default accessors (using the same
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 266 # name as the attribute) and calling <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually change things.
db045dbb » dhh 2004-11-23 Initial 267 # Example:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 268 #
db045dbb » dhh 2004-11-23 Initial 269 # class Song < ActiveRecord::Base
270 # # Uses an integer of seconds to hold the length of the song
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 271 #
db045dbb » dhh 2004-11-23 Initial 272 # def length=(minutes)
64092de2 » fxn 2008-05-02 Improve documentation cover... 273 # write_attribute(:length, minutes.to_i * 60)
db045dbb » dhh 2004-11-23 Initial 274 # end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 275 #
db045dbb » dhh 2004-11-23 Initial 276 # def length
0591c53e » dhh 2005-04-17 Made the dynamic finders us... 277 # read_attribute(:length) / 60
db045dbb » dhh 2004-11-23 Initial 278 # end
279 # end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 280 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 281 # You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt> instead of <tt>write_attribute(:attribute, value)</tt> and
282 # <tt>read_attribute(:attribute)</tt> as a shorter form.
0591c53e » dhh 2005-04-17 Made the dynamic finders us... 283 #
e4d845ef » Marcel Molina 2007-12-05 Document automatically gene... 284 # == Attribute query methods
285 #
286 # In addition to the basic accessors, query methods are also automatically available on the Active Record object.
287 # Query methods allow you to test whether an attribute value is present.
73673256 » jeremy 2007-12-09 Document Active Record exce... 288 #
e4d845ef » Marcel Molina 2007-12-05 Document automatically gene... 289 # For example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call
290 # to determine whether the user has a name:
291 #
292 # user = User.new(:name => "David")
293 # user.name? # => true
294 #
295 # anonymous = User.new(:name => "")
296 # anonymous.name? # => false
297 #
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 298 # == Accessing attributes before they have been typecasted
4eab3758 » dhh 2005-02-23 Finished polishing API docs 299 #
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 300 # Sometimes you want to be able to read the raw attribute data without having the column-determined typecast run its course first.
dc4eec11 » lifo 2008-05-09 Merge docrails: 301 # That can be done by using the <tt><attribute>_before_type_cast</tt> accessors that all attributes have. For example, if your Account model
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 302 # has a <tt>balance</tt> attribute, you can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.
4eab3758 » dhh 2005-02-23 Finished polishing API docs 303 #
304 # This is especially useful in validation situations where the user might supply a string for an integer field and you want to display
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 305 # the original string back in an error message. Accessing the attribute normally would typecast the string to 0, which isn't what you
4eab3758 » dhh 2005-02-23 Finished polishing API docs 306 # want.
307 #
ac8fd7df » dhh 2005-01-02 Added dynamic attribute-bas... 308 # == Dynamic attribute-based finders
309 #
a5a82d97 » dhh 2005-11-04 Added extension capabilitie... 310 # Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL. They work by
6dc9173a » dhh 2008-09-09 Missing doc updates 311 # appending the name of an attribute to <tt>find_by_</tt>, <tt>find_last_by_</tt>, or <tt>find_all_by_</tt>, so you get finders like <tt>Person.find_by_user_name</tt>,
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 312 # <tt>Person.find_all_by_last_name</tt>, and <tt>Payment.find_by_transaction_id</tt>. So instead of writing
a7e6e009 » Marcel Molina 2007-12-05 Documentation for find inco... 313 # <tt>Person.find(:first, :conditions => ["user_name = ?", user_name])</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
314 # And instead of writing <tt>Person.find(:all, :conditions => ["last_name = ?", last_name])</tt>, you just do <tt>Person.find_all_by_last_name(last_name)</tt>.
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 315 #
ac8fd7df » dhh 2005-01-02 Added dynamic attribute-bas... 316 # It's also possible to use multiple attributes in the same find by separating them with "_and_", so you get finders like
317 # <tt>Person.find_by_user_name_and_password</tt> or even <tt>Payment.find_by_purchaser_and_state_and_country</tt>. So instead of writing
a7e6e009 » Marcel Molina 2007-12-05 Documentation for find inco... 318 # <tt>Person.find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password])</tt>, you just do
ac8fd7df » dhh 2005-01-02 Added dynamic attribute-bas... 319 # <tt>Person.find_by_user_name_and_password(user_name, password)</tt>.
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 320 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 321 # It's even possible to use all the additional parameters to find. For example, the full interface for <tt>Payment.find_all_by_amount</tt>
322 # is actually <tt>Payment.find_all_by_amount(amount, options)</tt>. And the full interface to <tt>Person.find_by_user_name</tt> is
64092de2 » fxn 2008-05-02 Improve documentation cover... 323 # actually <tt>Person.find_by_user_name(user_name, options)</tt>. So you could call <tt>Payment.find_all_by_amount(50, :order => "created_on")</tt>.
567392bf » miloops 2008-09-01 Added find_last_by dynamic ... 324 # Also you may call <tt>Payment.find_last_by_amount(amount, options)</tt> returning the last record matching that amount and options.
959f362a » dhh 2005-01-02 Added find_all style to the... 325 #
a5a82d97 » dhh 2005-11-04 Added extension capabilitie... 326 # The same dynamic finder style can be used to create the object if it doesn't already exist. This dynamic finder is called with
5c47ceb3 » NZKoz 2008-03-25 Typo fix in documentation f... 327 # <tt>find_or_create_by_</tt> and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won't be set unless they are given in a block. For example:
a5a82d97 » dhh 2005-11-04 Added extension capabilitie... 328 #
329 # # No 'Summer' tag exists
330 # Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")
73673256 » jeremy 2007-12-09 Document Active Record exce... 331 #
a5a82d97 » dhh 2005-11-04 Added extension capabilitie... 332 # # Now the 'Summer' tag does exist
333 # Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
334 #
c10b2255 » dhh 2008-03-25 Fixed that ActiveRecord#Bas... 335 # # Now 'Bob' exist and is an 'admin'
336 # User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }
337 #
0432d151 » lifo 2008-07-16 Merge with docrails. Comment 338 # Use the <tt>find_or_initialize_by_</tt> finder if you want to return a new record without saving it first. Protected attributes won't be set unless they are given in a block. For example:
d19e4642 » sstephenson 2006-06-20 Added find_or_initialize_by... 339 #
340 # # No 'Winter' tag exists
341 # winter = Tag.find_or_initialize_by_name("Winter")
85fbb22f » dhh 2006-09-05 Backed out of new_record? t... 342 # winter.new_record? # true
d19e4642 » sstephenson 2006-06-20 Added find_or_initialize_by... 343 #
14cc8d2f » jeremy 2007-03-13 find_or_create_by_* takes a... 344 # To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of
345 # a list of parameters. For example:
346 #
347 # Tag.find_or_create_by_name(:name => "rails", :creator => current_user)
348 #
349 # That will either find an existing tag named "rails", or create a new one while setting the user that created it.
350 #
098fa943 » dhh 2005-02-07 Fixed documentation snafus ... 351 # == Saving arrays, hashes, and other non-mappable objects in text columns
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 352 #
353 # Active Record can serialize any object in text columns using YAML. To do so, you must specify this with a call to the class method +serialize+.
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 354 # This makes it possible to store arrays, hashes, and other non-mappable objects without doing any additional work. Example:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 355 #
db045dbb » dhh 2004-11-23 Initial 356 # class User < ActiveRecord::Base
357 # serialize :preferences
358 # end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 359 #
ca2eb16b » Marcel Molina 2006-04-26 Fix syntax error in documen... 360 # user = User.create(:preferences => { "background" => "black", "display" => large })
db045dbb » dhh 2004-11-23 Initial 361 # User.find(user.id).preferences # => { "background" => "black", "display" => large }
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 362 #
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 363 # You can also specify a class option as the second parameter that'll raise an exception if a serialized object is retrieved as a
39e1ac65 » lifo 2009-01-18 Merge docrails 364 # descendant of a class not in the hierarchy. Example:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 365 #
db045dbb » dhh 2004-11-23 Initial 366 # class User < ActiveRecord::Base
66f44e6c » dhh 2005-01-25 Updated documentation for s... 367 # serialize :preferences, Hash
db045dbb » dhh 2004-11-23 Initial 368 # end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 369 #
0591c53e » dhh 2005-04-17 Made the dynamic finders us... 370 # user = User.create(:preferences => %w( one two three ))
db045dbb » dhh 2004-11-23 Initial 371 # User.find(user.id).preferences # raises SerializationTypeMismatch
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 372 #
db045dbb » dhh 2004-11-23 Initial 373 # == Single table inheritance
374 #
7143d801 » Marcel Molina 2007-11-07 Smattering of grammatical f... 375 # Active Record allows inheritance by storing the name of the class in a column that by default is named "type" (can be changed
db045dbb » dhh 2004-11-23 Initial 376 # by overwriting <tt>Base.inheritance_column</tt>). This means that an inheritance looking like this:
377 #
378 # class Company < ActiveRecord::Base; end
379 # class Firm < Company; end
380 # class Client < Company; end
381 # class PriorityClient < Client; end
382 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 383 # When you do <tt>Firm.create(:name => "37signals")</tt>, this record will be saved in the companies table with type = "Firm". You can then
384 # fetch this row again using <tt>Company.find(:first, "name = '37signals'")</tt> and it will return a Firm object.
db045dbb » dhh 2004-11-23 Initial 385 #
f033833f » dhh 2004-12-16 Improving documentation... 386 # If you don't have a type column defined in your table, single-table inheritance won't be triggered. In that case, it'll work just
387 # like normal subclasses with no special magic for differentiating between them or reloading the right type with find.
388 #
db045dbb » dhh 2004-11-23 Initial 389 # Note, all the attributes for all the cases are kept in the same table. Read more:
390 # http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 391 #
db045dbb » dhh 2004-11-23 Initial 392 # == Connection to multiple databases in different models
393 #
394 # Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection.
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 395 # All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection.
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 396 # For example, if Course is an ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
397 # and Course and all of its subclasses will use this connection instead.
db045dbb » dhh 2004-11-23 Initial 398 #
399 # This feature is implemented by keeping a connection pool in ActiveRecord::Base that is a Hash indexed by the class. If a connection is
400 # requested, the retrieve_connection method will go up the class-hierarchy until a connection is found in the connection pool.
401 #
402 # == Exceptions
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 403 #
dc4eec11 » lifo 2008-05-09 Merge docrails: 404 # * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
405 # * AdapterNotSpecified - The configuration hash used in <tt>establish_connection</tt> didn't include an
db045dbb » dhh 2004-11-23 Initial 406 # <tt>:adapter</tt> key.
dc4eec11 » lifo 2008-05-09 Merge docrails: 407 # * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a non-existent adapter
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 408 # (or a bad spelling of an existing one).
dc4eec11 » lifo 2008-05-09 Merge docrails: 409 # * AssociationTypeMismatch - The object assigned to the association wasn't of the type specified in the association definition.
410 # * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
411 # * ConnectionNotEstablished+ - No connection has been established. Use <tt>establish_connection</tt> before querying.
412 # * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist
413 # or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal
414 # nothing was found, please check its documentation for further details.
415 # * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
416 # * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
417 # <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of AttributeAssignmentError
d2fefbe9 » dhh 2005-03-06 Added MultiparameterAssignm... 418 # objects that should be inspected to determine which attributes triggered the errors.
dc4eec11 » lifo 2008-05-09 Merge docrails: 419 # * AttributeAssignmentError - An error occurred while doing a mass assignment through the <tt>attributes=</tt> method.
d2fefbe9 » dhh 2005-03-06 Added MultiparameterAssignm... 420 # You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error.
57070277 » dhh 2005-09-11 Added better exception erro... 421 #
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 422 # *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
dc4eec11 » lifo 2008-05-09 Merge docrails: 423 # So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
db045dbb » dhh 2004-11-23 Initial 424 # instances in the current object space.
425 class Base
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 426 ##
dbbae5e0 » lifo 2008-12-06 Merge with docrails 427 # :singleton-method:
db045dbb » dhh 2004-11-23 Initial 428 # Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then passed
429 # on to any new database connections made and which can be retrieved on both a class and instance level by calling +logger+.
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 430 cattr_accessor :logger, :instance_writer => false
e6941149 » jeremy 2007-09-13 Deprecation: removed Reload... 431
db045dbb » dhh 2004-11-23 Initial 432 def self.inherited(child) #:nodoc:
433 @@subclasses[self] ||= []
434 @@subclasses[self] << child
435 super
436 end
e6941149 » jeremy 2007-09-13 Deprecation: removed Reload... 437
fed7d334 » dhh 2006-03-27 Fixed documentation 438 def self.reset_subclasses #:nodoc:
bfbf6bba » jamis 2005-10-15 Allow ARStore::Session to i... 439 nonreloadables = []
e7f61eab » jamis 2005-10-15 squash the memleak in dev m... 440 subclasses.each do |klass|
c08547d2 » josh 2008-06-03 Namespace Inflector, Depend... Comment 441 unless ActiveSupport::Dependencies.autoloaded? klass
bfbf6bba » jamis 2005-10-15 Allow ARStore::Session to i... 442 nonreloadables << klass
443 next
444 end
e7f61eab » jamis 2005-10-15 squash the memleak in dev m... 445 klass.instance_variables.each { |var| klass.send(:remove_instance_variable, var) }
446 klass.instance_methods(false).each { |m| klass.send :undef_method, m }
447 end
bfbf6bba » jamis 2005-10-15 Allow ARStore::Session to i... 448 @@subclasses = {}
449 nonreloadables.each { |klass| (@@subclasses[klass.superclass] ||= []) << klass }
3c0129af » dhh 2005-09-20 Fixed memory leak with Acti... 450 end
451
db045dbb » dhh 2004-11-23 Initial 452 @@subclasses = {}
c3aa2bcd » Manfred 2009-03-10 Ensure nested with_scope me... 453
dbbae5e0 » lifo 2008-12-06 Merge with docrails 454 ##
455 # :singleton-method:
a2932784 » lifo 2008-10-05 Merge docrails 456 # Contains the database configuration - as is typically stored in config/database.yml -
457 # as a Hash.
458 #
459 # For example, the following database.yml...
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 460 #
a2932784 » lifo 2008-10-05 Merge docrails 461 # development:
462 # adapter: sqlite3
463 # database: db/development.sqlite3
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 464 #
a2932784 » lifo 2008-10-05 Merge docrails 465 # production:
466 # adapter: sqlite3
467 # database: db/production.sqlite3
468 #
469 # ...would result in ActiveRecord::Base.configurations to look like this:
470 #
471 # {
472 # 'development' => {
473 # 'adapter' => 'sqlite3',
474 # 'database' => 'db/development.sqlite3'
475 # },
476 # 'production' => {
477 # 'adapter' => 'sqlite3',
478 # 'database' => 'db/production.sqlite3'
479 # }
480 # }
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 481 cattr_accessor :configurations, :instance_writer => false
c4a36349 » jeremy 2005-06-12 Corrected @@configurations ... 482 @@configurations = {}
483
dbbae5e0 » lifo 2008-12-06 Merge with docrails 484 ##
485 # :singleton-method:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 486 # Accessor for the prefix type that will be prepended to every primary key column name. The options are :table_name and
db045dbb » dhh 2004-11-23 Initial 487 # :table_name_with_underscore. If the first is specified, the Product class will look for "productid" instead of "id" as
488 # the primary column. If the latter is specified, the Product class will look for "product_id" instead of "id". Remember
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 489 # that this is a global setting for all Active Records.
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 490 cattr_accessor :primary_key_prefix_type, :instance_writer => false
db045dbb » dhh 2004-11-23 Initial 491 @@primary_key_prefix_type = nil
492
dbbae5e0 » lifo 2008-12-06 Merge with docrails 493 ##
494 # :singleton-method:
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 495 # Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all
098fa943 » dhh 2005-02-07 Fixed documentation snafus ... 496 # table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace
db045dbb » dhh 2004-11-23 Initial 497 # for tables in a shared database. By default, the prefix is the empty string.
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 498 cattr_accessor :table_name_prefix, :instance_writer => false
db045dbb » dhh 2004-11-23 Initial 499 @@table_name_prefix = ""
500
dbbae5e0 » lifo 2008-12-06 Merge with docrails 501 ##
502 # :singleton-method:
db045dbb » dhh 2004-11-23 Initial 503 # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
504 # "people_basecamp"). By default, the suffix is the empty string.
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 505 cattr_accessor :table_name_suffix, :instance_writer => false
db045dbb » dhh 2004-11-23 Initial 506 @@table_name_suffix = ""
507
dbbae5e0 » lifo 2008-12-06 Merge with docrails 508 ##
509 # :singleton-method:
84a14f26 » jeremy 2007-10-07 Raise ProtectedAttributeAss... 510 # Indicates whether table names should be the pluralized versions of the corresponding class names.
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 511 # If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
db045dbb » dhh 2004-11-23 Initial 512 # See table_name for the full rules on table/class naming. This is true, by default.
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 513 cattr_accessor :pluralize_table_names, :instance_writer => false
db045dbb » dhh 2004-11-23 Initial 514 @@pluralize_table_names = true
515
dbbae5e0 » lifo 2008-12-06 Merge with docrails 516 ##
517 # :singleton-method:
84a14f26 » jeremy 2007-10-07 Raise ProtectedAttributeAss... 518 # Determines whether to use ANSI codes to colorize the logging statements committed by the connection adapter. These colors
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 519 # make it much easier to overview things during debugging (when used through a reader like +tail+ and on a black background), but
911614df » dhh 2005-03-06 Added ActiveRecord::Base.co... 520 # may complicate matters if you use software like syslog. This is true, by default.
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 521 cattr_accessor :colorize_logging, :instance_writer => false
911614df » dhh 2005-03-06 Added ActiveRecord::Base.co... 522 @@colorize_logging = true
523
dbbae5e0 » lifo 2008-12-06 Merge with docrails 524 ##
525 # :singleton-method:
60de8c11 » dhh 2004-12-28 Added Base.default_timezone... 526 # Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates and times from the database.
527 # This is set to :local by default.
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 528 cattr_accessor :default_timezone, :instance_writer => false
60de8c11 » dhh 2004-12-28 Added Base.default_timezone... 529 @@default_timezone = :local
d8641ca3 » jeremy 2006-03-01 CHANGED DEFAULT: set Active... 530
dbbae5e0 » lifo 2008-12-06 Merge with docrails 531 ##
532 # :singleton-method:
24c3599c » sstephenson 2005-10-12 Support using different dat... 533 # Specifies the format to use when dumping the database schema with Rails'
534 # Rakefile. If :sql, the schema is dumped as (potentially database-
73673256 » jeremy 2007-12-09 Document Active Record exce... 535 # specific) SQL statements. If :ruby, the schema is dumped as an
24c3599c » sstephenson 2005-10-12 Support using different dat... 536 # ActiveRecord::Schema file which can be loaded into any database that
537 # supports migrations. Use :ruby if you want to have different database
538 # adapters for, e.g., your development and test environments.
1a11bffd » technoweenie 2007-01-27 Don't create instance write... 539 cattr_accessor :schema_format , :instance_writer => false
660952e5 » dhh 2006-02-26 CHANGED DEFAULT: ActiveReco... 540 @@schema_format = :ruby
3b0e1d90 » josh 2008-05-14 Prefer string core_ext infl... Comment 541
dbbae5e0 » lifo 2008-12-06 Merge with docrails 542 ##
543 # :singleton-method:
bbab6391 » codetocustomer 2008-07-16 Set config.active_record.ti... 544 # Specify whether or not to use timestamps for migration numbers
545 cattr_accessor :timestamped_migrations , :instance_writer => false
546 @@timestamped_migrations = true
547
bca8751e » divoxx 2008-04-11 Add ActiveRecord option to ... Comment 548 # Determine whether to store the full constant name including namespace when using STI
549 superclass_delegating_accessor :store_full_sti_class
550 self.store_full_sti_class = false
3b0e1d90 » josh 2008-05-14 Prefer string core_ext infl... Comment 551
2530d0ee » lifo 2008-11-16 Added default_scope to Base... Comment 552 # Stores the default scope for the class
553 class_inheritable_accessor :default_scoping, :instance_writer => false
554 self.default_scoping = []
555
db045dbb » dhh 2004-11-23 Initial 556 class << self # Class methods
d5a4d5ab » dhh 2008-03-12 Added ActiveRecord::Base.fi... 557 # Find operates with four different retrieval approaches:
76690111 » dhh 2005-04-17 Fixes for postgresql testin... 558 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 559 # * 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]).
76690111 » dhh 2005-04-17 Fixes for postgresql testin... 560 # If no record can be found for all of the listed ids, then RecordNotFound will be raised.
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 561 # * Find first - This will return the first record matched by the options used. These options can either be specific
562 # conditions or merely an order. If no record can be matched, +nil+ is returned. Use
563 # <tt>Model.find(:first, *args)</tt> or its shortcut <tt>Model.first(*args)</tt>.
564 # * Find last - This will return the last record matched by the options used. These options can either be specific
565 # conditions or merely an order. If no record can be matched, +nil+ is returned. Use
566 # <tt>Model.find(:last, *args)</tt> or its shortcut <tt>Model.last(*args)</tt>.
567 # * Find all - This will return all the records matched by the options used.
568 # If no records are found, an empty array is returned. Use
569 # <tt>Model.find(:all, *args)</tt> or its shortcut <tt>Model.all(*args)</tt>.
570 #
571 # All approaches accept an options hash as their last parameter.
572 #
a2932784 » lifo 2008-10-05 Merge docrails 573 # ==== Parameters
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 574 #
9cb54008 » lifo 2008-10-16 Merge docrails 575 # * <tt>:conditions</tt> - An SQL fragment like "administrator = 1", <tt>[ "user_name = ?", username ]</tt>, or <tt>["user_name = :user_name", { :user_name => user_name }]</tt>. See conditions in the intro.
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 576 # * <tt>:order</tt> - An SQL fragment like "created_at DESC, name".
577 # * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause.
97403ad5 » miloops 2008-11-21 Add :having option to find,... 578 # * <tt>:having</tt> - Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns. Uses the <tt>HAVING</tt> SQL-clause.
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 579 # * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned.
580 # * <tt>:offset</tt> - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
39e1ac65 » lifo 2009-01-18 Merge docrails 581 # * <tt>:joins</tt> - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed),
582 # named associations in the same form used for the <tt>:include</tt> option, which will perform an <tt>INNER JOIN</tt> on the associated table(s),
583 # or an array containing a mixture of both strings and named associations.
9661395d » Marcel Molina 2007-12-13 Remove references to nonexi... 584 # 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.
64092de2 » fxn 2008-05-02 Improve documentation cover... 585 # Pass <tt>:readonly => false</tt> to override.
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 586 # * <tt>:include</tt> - Names associations that should be loaded alongside. The symbols named refer
515886a5 » dhh 2005-04-18 Added documentation for new... 587 # to already defined associations. See eager loading under Associations.
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 588 # * <tt>:select</tt> - By default, this is "*" as in "SELECT * FROM", but can be changed if you, for example, want to do a join but not
6ef35461 » lifo 2008-09-03 Merge docrails 589 # include the joined columns. Takes a string with the SELECT SQL fragment (e.g. "id, name").
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 590 # * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
73673256 » jeremy 2007-12-09 Document Active Record exce... 591 # of a database view).
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 592 # * <tt>:readonly</tt> - Mark the returned records read-only so they cannot be saved or updated.
593 # * <tt>:lock</tt> - An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE".
64092de2 » fxn 2008-05-02 Improve documentation cover... 594 # <tt>:lock => true</tt> gives connection's default exclusive lock, usually "FOR UPDATE".
76690111 » dhh 2005-04-17 Fixes for postgresql testin... 595 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 596 # ==== Examples
597 #
598 # # find by id
db045dbb » dhh 2004-11-23 Initial 599 # Person.find(1) # returns the object for ID = 1
600 # Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
601 # Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
7143d801 » Marcel Molina 2007-11-07 Smattering of grammatical f... 602 # Person.find([1]) # returns an array for the object with ID = 1
515886a5 » dhh 2005-04-18 Added documentation for new... 603 # Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC")
604 #
1e9e198c » jeremy 2007-03-06 Note that find results may ... 605 # Note that returned records may not be in the same order as the ids you
64092de2 » fxn 2008-05-02 Improve documentation cover... 606 # provide since database rows are unordered. Give an explicit <tt>:order</tt>
1e9e198c » jeremy 2007-03-06 Note that find results may ... 607 # to ensure the results are sorted.
608 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 609 # ==== Examples
610 #
611 # # find first
7d010055 » dhh 2005-04-18 Fixed documentation and pre... 612 # Person.find(:first) # returns the first object fetched by SELECT * FROM people
515886a5 » dhh 2005-04-18 Added documentation for new... 613 # Person.find(:first, :conditions => [ "user_name = ?", user_name])
9cb54008 » lifo 2008-10-16 Merge docrails 614 # Person.find(:first, :conditions => [ "user_name = :u", { :u => user_name }])
515886a5 » dhh 2005-04-18 Added documentation for new... 615 # Person.find(:first, :order => "created_on DESC", :offset => 5)
616 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 617 # # find last
d5a4d5ab » dhh 2008-03-12 Added ActiveRecord::Base.fi... 618 # Person.find(:last) # returns the last object fetched by SELECT * FROM people
619 # Person.find(:last, :conditions => [ "user_name = ?", user_name])
620 # Person.find(:last, :order => "created_on DESC", :offset => 5)
621 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 622 # # find all
7d010055 » dhh 2005-04-18 Fixed documentation and pre... 623 # Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people
515886a5 » dhh 2005-04-18 Added documentation for new... 624 # Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
aa4af60a » lifo 2008-04-04 Improve documentation. 625 # Person.find(:all, :conditions => { :friends => ["Bob", "Steve", "Fred"] }
515886a5 » dhh 2005-04-18 Added documentation for new... 626 # Person.find(:all, :offset => 10, :limit => 10)
627 # Person.find(:all, :include => [ :account, :friends ])
33092681 » jeremy 2005-11-10 Add :group option, correspo... 628 # Person.find(:all, :group => "category")
15aa6e05 » jeremy 2006-06-19 r4644@asus: jeremy | 2006... 629 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 630 # Example for find with a lock: Imagine two concurrent transactions:
631 # each will read <tt>person.visits == 2</tt>, add 1 to it, and save, resulting
632 # in two saves of <tt>person.visits = 3</tt>. By locking the row, the second
15aa6e05 » jeremy 2006-06-19 r4644@asus: jeremy | 2006... 633 # transaction has to wait until the first is finished; we get the
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 634 # expected <tt>person.visits == 4</tt>.
635 #
15aa6e05 » jeremy 2006-06-19 r4644@asus: jeremy | 2006... 636 # Person.transaction do
637 # person = Person.find(1, :lock => true)
638 # person.visits += 1
639 # person.save!
640 # end
6bd672eb » dhh 2005-01-01 Added that Base#find takes ... 641 def find(*args)
edd68a58 » dhh 2007-07-24 Refactored in use of extrac... 642 options = args.extract_options!
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 643 validate_find_options(options)
644 set_readonly_option!(options)
64fcb752 » jeremy 2005-10-14 r3618@sedna: jeremy | 200... 645
abc895b8 » dhh 2005-04-03 Added new Base.find API and... 646 case args.first
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 647 when :first then find_initial(options)
d5a4d5ab » dhh 2008-03-12 Added ActiveRecord::Base.fi... 648 when :last then find_last(options)
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 649 when :all then find_every(options)
650 else find_from_ids(args, options)
db045dbb » dhh 2004-11-23 Initial 651 end
652 end
3b0e1d90 » josh 2008-05-14 Prefer string core_ext infl... Comment 653
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 654 # A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
655 # same arguments to this method as you can to <tt>find(:first)</tt>.
c6f2af5c » dhh 2008-03-24 Added ActiveRecord#Base.all... 656 def first(*args)
657 find(:first, *args)
658 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 659
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 660 # A convenience wrapper for <tt>find(:last, *args)</tt>. You can pass in all the
661 # same arguments to this method as you can to <tt>find(:last)</tt>.
c6f2af5c » dhh 2008-03-24 Added ActiveRecord#Base.all... 662 def last(*args)
663 find(:last, *args)
664 end
3b0e1d90 » josh 2008-05-14 Prefer string core_ext infl... Comment 665
23c168a4 » Emilio Tagua 2009-10-05 Initial documentation to Ba... 666 # Returns an ActiveRecord::Relation object. You can pass in all the same arguments to this method as you can
667 # to find(:all).
0a6980f2 » David Heinemeier Hansson 2008-04-28 Let Base.all use conditions... 668 def all(*args)
c01c21b3 » Emilio Tagua 2009-09-01 Added association preload t... 669 options = args.extract_options!
670
3747f896 » Emilio Tagua 2009-10-05 Moved relation's test to re... 671 if options.empty? && !scoped?(:find)
c01c21b3 » Emilio Tagua 2009-09-01 Added association preload t... 672 relation = arel_table
c1cbf02e » Emilio Tagua 2009-07-31 Added ActiveRecord::Relatio... 673 else
65f055a3 » Emilio Tagua 2009-10-05 Added eager loading support... 674 relation = construct_finder_arel(options)
c01c21b3 » Emilio Tagua 2009-09-01 Added association preload t... 675 include_associations = merge_includes(scope(:find, :include), options[:include])
676
65f055a3 » Emilio Tagua 2009-10-05 Added eager loading support... 677 if include_associations.any?
678 if references_eager_loaded_tables?(options)
679 relation.eager_load(include_associations)
680 else
c01c21b3 » Emilio Tagua 2009-09-01 Added association preload t... 681 relation.preload(include_associations)
65f055a3 » Emilio Tagua 2009-10-05 Added eager loading support... 682 end
c01c21b3 » Emilio Tagua 2009-09-01 Added association preload t... 683 end
c1cbf02e » Emilio Tagua 2009-07-31 Added ActiveRecord::Relatio... 684 end
c01c21b3 » Emilio Tagua 2009-09-01 Added association preload t... 685 relation
0a6980f2 » David Heinemeier Hansson 2008-04-28 Let Base.all use conditions... 686 end
3b0e1d90 » josh 2008-05-14 Prefer string core_ext infl... Comment 687
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 688 # Executes a custom SQL query against your database and returns all the results. The results will
73673256 » jeremy 2007-12-09 Document Active Record exce... 689 # be returned as an array with columns requested encapsulated as attributes of the model you call
a2932784 » lifo 2008-10-05 Merge docrails 690 # this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
691 # a Product object with the attributes you specified in the SQL query.
edf32cea » Marcel Molina 2007-12-05 More complete documentation... 692 #
73673256 » jeremy 2007-12-09 Document Active Record exce... 693 # If you call a complicated SQL query which spans multiple tables the columns specified by the
694 # SELECT will be attributes of the model, whether or not they are columns of the corresponding
edf32cea » Marcel Molina 2007-12-05 More complete documentation... 695 # table.
696 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 697 # The +sql+ parameter is a full SQL query as a string. It will be called as is, there will be
73673256 » jeremy 2007-12-09 Document Active Record exce... 698 # no database agnostic conversions performed. This should be a last resort because using, for example,
699 # MySQL specific terms will lock you to using that particular database engine or require you to
a2932784 » lifo 2008-10-05 Merge docrails 700 # change your call if you switch engines.
edf32cea » Marcel Molina 2007-12-05 More complete documentation... 701 #
702 # ==== Examples
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 703 # # A simple SQL query spanning multiple tables
edf32cea » Marcel Molina 2007-12-05 More complete documentation... 704 # Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
705 # > [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
706 #
707 # # You can use the same string replacement techniques as you can with ActiveRecord#find
708 # Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
709 # > [#<Post:0x36bff9c @attributes={"first_name"=>"The Cheap Man Buys Twice"}>, ...]
db045dbb » dhh 2004-11-23 Initial 710 def find_by_sql(sql)
6e3d2a79 » jeremy 2008-08-21 Revert "Performance: freeze... 711 connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) }
db045dbb » dhh 2004-11-23 Initial 712 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 713
dbbae5e0 » lifo 2008-12-06 Merge with docrails 714 # Returns true if a record exists in the table that matches the +id+ or
5a8f7646 » smtlaissezfaire 2009-01-31 Add ActiveRecord::Base.exis... 715 # conditions given, or false otherwise. The argument can take five forms:
dbbae5e0 » lifo 2008-12-06 Merge with docrails 716 #
717 # * Integer - Finds the record with this primary key.
718 # * String - Finds the record with a primary key corresponding to this
719 # string (such as <tt>'5'</tt>).
720 # * Array - Finds the record that matches these +find+-style conditions
721 # (such as <tt>['color = ?', 'red']</tt>).
722 # * Hash - Finds the record that matches these +find+-style conditions
723 # (such as <tt>{:color => 'red'}</tt>).
5a8f7646 » smtlaissezfaire 2009-01-31 Add ActiveRecord::Base.exis... 724 # * No args - Returns false if the table is empty, true otherwise.
971ed153 » Marcel Molina 2007-12-05 Document API for exists?'s ... 725 #
dbbae5e0 » lifo 2008-12-06 Merge with docrails 726 # For more information about specifying conditions as a Hash or Array,
727 # see the Conditions section in the introduction to ActiveRecord::Base.
971ed153 » Marcel Molina 2007-12-05 Document API for exists?'s ... 728 #
dbbae5e0 » lifo 2008-12-06 Merge with docrails 729 # Note: You can't pass in a condition as a string (like <tt>name =
730 # 'Jamie'</tt>), since it would be sanitized and then queried against
731 # the primary key column, like <tt>id = 'name = \'Jamie\''</tt>.
971ed153 » Marcel Molina 2007-12-05 Document API for exists?'s ... 732 #
733 # ==== Examples
abc895b8 » dhh 2005-04-03 Added new Base.find API and... 734 # Person.exists?(5)
58ebf302 » jeremy 2006-08-03 The exists? class method sh... 735 # Person.exists?('5')
8085cbfd » dhh 2006-08-03 Added support for condition... 736 # Person.exists?(:name => "David")
58ebf302 » jeremy 2006-08-03 The exists? class method sh... 737 # Person.exists?(['name LIKE ?', "%#{query}%"])
5a8f7646 » smtlaissezfaire 2009-01-31 Add ActiveRecord::Base.exis... 738 # Person.exists?
739 def exists?(id_or_conditions = {})
afcbdfc1 » peter 2009-05-14 Changed ActiveRecord::Base#... 740 find_initial(
741 :select => "#{quoted_table_name}.#{primary_key}",
742 :conditions => expand_id_conditions(id_or_conditions)) ? true : false
db045dbb » dhh 2004-11-23 Initial 743 end
abc895b8 » dhh 2005-04-03 Added new Base.find API and... 744
73673256 » jeremy 2007-12-09 Document Active Record exce... 745 # Creates an object (or multiple objects) and saves it to the database, if validations pass.
a23bea7c » Marcel Molina 2007-12-05 Document API for create's a... 746 # The resulting object is returned whether the object was saved successfully to the database or not.
747 #
748 # The +attributes+ parameter can be either be a Hash or an Array of Hashes. These Hashes describe the
749 # attributes on the objects that are to be created.
750 #
751 # ==== Examples
752 # # Create a single new object
753 # User.create(:first_name => 'Jamie')
dd120ede » dhh 2008-04-30 Added block-setting of attr... 754 #
a23bea7c » Marcel Molina 2007-12-05 Document API for create's a... 755 # # Create an Array of new objects
dc4eec11 » lifo 2008-05-09 Merge docrails: 756 # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
dd120ede » dhh 2008-04-30 Added block-setting of attr... 757 #
758 # # Create a single object and pass it into a block to set other attributes.
759 # User.create(:first_name => 'Jamie') do |u|
760 # u.is_admin = false
761 # end
762 #
763 # # Creating an Array of new objects using a block, where the block is executed for each object:
dc4eec11 » lifo 2008-05-09 Merge docrails: 764 # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
dd120ede » dhh 2008-04-30 Added block-setting of attr... 765 # u.is_admin = false
3b0e1d90 » josh 2008-05-14 Prefer string core_ext infl... Comment 766 # end
dd120ede » dhh 2008-04-30 Added block-setting of attr... 767 def create(attributes = nil, &block)
efa81dad » dhh 2005-01-25 Added the option of supplyi... 768 if attributes.is_a?(Array)
dd120ede » dhh 2008-04-30 Added block-setting of attr... 769 attributes.collect { |attr| create(attr, &block) }
efa81dad » dhh 2005-01-25 Added the option of supplyi... 770 else
771 object = new(attributes)
dd120ede » dhh 2008-04-30 Added block-setting of attr... 772 yield(object) if block_given?
efa81dad » dhh 2005-01-25 Added the option of supplyi... 773 object.save
774 object
775 end
db045dbb » dhh 2004-11-23 Initial 776 end
777
1b7a18de » Marcel Molina 2007-12-05 Document options and add ex... 778 # Updates an object (or multiple objects) and saves it to the database, if validations pass.
779 # The resulting object is returned whether the object was saved successfully to the database or not.
5e99422d » dhh 2006-02-25 Updated docs (closes #3799)... 780 #
a2932784 » lifo 2008-10-05 Merge docrails 781 # ==== Parameters
5e99422d » dhh 2006-02-25 Updated docs (closes #3799)... 782 #
dc4eec11 » lifo 2008-05-09 Merge docrails: 783 # * +id+ - This should be the id or an array of ids to be updated.
18eb80cc » lifo 2009-03-16 Merge docrails 784 # * +attributes+ - This should be a hash of attributes to be set on the object, or an array of hashes.
1b7a18de » Marcel Molina 2007-12-05 Document options and add ex... 785 #
786 # ==== Examples
787 #
788 # # Updating one record:
18eb80cc » lifo 2009-03-16 Merge docrails 789 # Person.update(15, :user_name => 'Samuel', :group => 'expert')
73673256 » jeremy 2007-12-09 Document Active Record exce... 790 #
1b7a18de » Marcel Molina 2007-12-05 Document options and add ex... 791 # # Updating multiple records:
dc4eec11 » lifo 2008-05-09 Merge docrails: 792 # people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
5e99422d » dhh 2006-02-25 Updated docs (closes #3799)... 793 # Person.update(people.keys, people.values)
db045dbb » dhh 2004-11-23 Initial 794 def update(id, attributes)
efa81dad » dhh 2005-01-25 Added the option of supplyi... 795 if id.is_a?(Array)
796 idx = -1
8b5f4e47 » jeremy 2007-12-22 Ruby 1.9 compat: fix warnin... 797 id.collect { |one_id| idx += 1; update(one_id, attributes[idx]) }
efa81dad » dhh 2005-01-25 Added the option of supplyi... 798 else
799 object = find(id)
800 object.update_attributes(attributes)
801 object
802 end
db045dbb » dhh 2004-11-23 Initial 803 end
804
39e1ac65 » lifo 2009-01-18 Merge docrails 805 # Deletes the row with a primary key matching the +id+ argument, using a
806 # SQL +DELETE+ statement, and returns the number of rows deleted. Active
807 # Record objects are not instantiated, so the object's callbacks are not
808 # executed, including any <tt>:dependent</tt> association options or
809 # Observer methods.
73673256 » jeremy 2007-12-09 Document Active Record exce... 810 #
39e1ac65 » lifo 2009-01-18 Merge docrails 811 # You can delete multiple rows at once by passing an Array of <tt>id</tt>s.
6a45e01b » Marcel Molina 2007-12-05 Document options and add ex... 812 #
39e1ac65 » lifo 2009-01-18 Merge docrails 813 # Note: Although it is often much faster than the alternative,
814 # <tt>#destroy</tt>, skipping callbacks might bypass business logic in
815 # your application that ensures referential integrity or performs other
816 # essential jobs.
6a45e01b » Marcel Molina 2007-12-05 Document options and add ex... 817 #
818 # ==== Examples
819 #
39e1ac65 » lifo 2009-01-18 Merge docrails 820 # # Delete a single row
6a45e01b » Marcel Molina 2007-12-05 Document options and add ex... 821 # Todo.delete(1)
73673256 » jeremy 2007-12-09 Document Active Record exce... 822 #
39e1ac65 » lifo 2009-01-18 Merge docrails 823 # # Delete multiple rows
824 # Todo.delete([2,3,4])
648b8fda » dhh 2004-12-17 Added Base.destroy and Base... 825 def delete(id)
98165fd3 » jeremy 2007-03-08 Consistently quote primary ... 826 delete_all([ "#{connection.quote_column_name(primary_key)} IN (?)", id ])
648b8fda » dhh 2004-12-17 Added Base.destroy and Base... 827 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 828
ed69b38a » Marcel Molina 2007-12-05 Document options and add ex... 829 # Destroy an object (or multiple objects) that has the given id, the object is instantiated first,
830 # therefore all callbacks and filters are fired off before the object is deleted. This method is
831 # less efficient than ActiveRecord#delete but allows cleanup methods and other actions to be run.
73673256 » jeremy 2007-12-09 Document Active Record exce... 832 #
833 # This essentially finds the object (or multiple objects) with the given id, creates a new object
ed69b38a » Marcel Molina 2007-12-05 Document options and add ex... 834 # from the attributes, and then calls destroy on it.
835 #
a2932784 » lifo 2008-10-05 Merge docrails 836 # ==== Parameters
73673256 » jeremy 2007-12-09 Document Active Record exce... 837 #
dc4eec11 » lifo 2008-05-09 Merge docrails: 838 # * +id+ - Can be either an Integer or an Array of Integers.
ed69b38a » Marcel Molina 2007-12-05 Document options and add ex... 839 #
840 # ==== Examples
841 #
842 # # Destroy a single object
843 # Todo.destroy(1)
73673256 » jeremy 2007-12-09 Document Active Record exce... 844 #
ed69b38a » Marcel Molina 2007-12-05 Document options and add ex... 845 # # Destroy multiple objects
846 # todos = [1,2,3]
847 # Todo.destroy(todos)
648b8fda » dhh 2004-12-17 Added Base.destroy and Base... 848 def destroy(id)
8b5f4e47 » jeremy 2007-12-22 Ruby 1.9 compat: fix warnin... 849 if id.is_a?(Array)
850 id.map { |one_id| destroy(one_id) }
851 else
852 find(id).destroy
853 end
648b8fda » dhh 2004-12-17 Added Base.destroy and Base... 854 end
855
4f1d353b » Marcel Molina 2007-12-05 Document options and add ex... 856 # Updates all records with details given if they match a set of conditions supplied, limits and order can
6ef35461 » lifo 2008-09-03 Merge docrails 857 # also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the
f97832b1 » lifo 2009-03-24 Merge docrails 858 # database. It does not instantiate the involved models and it does not trigger Active Record callbacks
859 # or validations.
a38f28ff » jeremy 2007-03-17 Base.update_all :order and ... 860 #
a2932784 » lifo 2008-10-05 Merge docrails 861 # ==== Parameters
4f1d353b » Marcel Molina 2007-12-05 Document options and add ex... 862 #
f97832b1 » lifo 2009-03-24 Merge docrails 863 # * +updates+ - A string, array, or hash representing the SET part of an SQL statement.
864 # * +conditions+ - A string, array, or hash representing the WHERE part of an SQL statement. See conditions in the intro.
6ef35461 » lifo 2008-09-03 Merge docrails 865 # * +options+ - Additional options are <tt>:limit</tt> and <tt>:order</tt>, see the examples for usage.
4f1d353b » Marcel Molina 2007-12-05 Document options and add ex... 866 #
867 # ==== Examples
868 #
f97832b1 » lifo 2009-03-24 Merge docrails 869 # # Update all customers with the given attributes
870 # Customer.update_all :wants_email => true
73673256 » jeremy 2007-12-09 Document Active Record exce... 871 #
f97832b1 » lifo 2009-03-24 Merge docrails 872 # # Update all books with 'Rails' in their title
873 # Book.update_all "author = 'David'", "title LIKE '%Rails%'"
4f1d353b » Marcel Molina 2007-12-05 Document options and add ex... 874 #
f97832b1 » lifo 2009-03-24 Merge docrails 875 # # Update all avatars migrated more than a week ago
e033b5d0 » lifo 2009-07-25 Merge docrails 876 # Avatar.update_all ['migrated_at = ?', Time.now.utc], ['migrated_at > ?', 1.week.ago]
f97832b1 » lifo 2009-03-24 Merge docrails 877 #
878 # # Update all books that match our conditions, but limit it to 5 ordered by date
879 # Book.update_all "author = 'David'", "title LIKE '%Rails%'", :order => 'created_at', :limit => 5
a38f28ff » jeremy 2007-03-17 Base.update_all :order and ... 880 def update_all(updates, conditions = nil, options = {})
7be3e3ba » Emilio Tagua 2009-06-10 Use ARel in SQL generation ... 881 scope = scope(:find)
7c9851db » tarmo 2008-09-10 Support :limit on update_al... 882
79e951ca » Emilio Tagua 2009-08-18 Use finder options as relat... 883 relation = arel_table
71528c29 » Emilio Tagua 2009-06-10 Initial update_all migration 884
885 if conditions = construct_conditions(conditions, scope)
66fbcc1d » Emilio Tagua 2009-08-18 Use immutable relation obje... 886 relation = relation.conditions(Arel::SqlLiteral.new(conditions))
71528c29 » Emilio Tagua 2009-06-10 Initial update_all migration 887 end
05874620 » Emilio Tagua 2009-06-10 Revert "Use ARel in SQL gen... 888
66fbcc1d » Emilio Tagua 2009-08-18 Use immutable relation obje... 889 relation = if options.has_key?(:limit) || (scope && scope[:limit])
7c9851db » tarmo 2008-09-10 Support :limit on update_al... 890 # Only take order from scope if limit is also provided by scope, this
891 # is useful for updating a has_many association with a limit.
66fbcc1d » Emilio Tagua 2009-08-18 Use immutable relation obje... 892 relation.order(construct_order(options[:order], scope)).limit(construct_limit(options[:limit], scope))
7c9851db » tarmo 2008-09-10 Support :limit on update_al... 893 else
66fbcc1d » Emilio Tagua 2009-08-18 Use immutable relation obje... 894 relation.order(options[:order])
7c9851db » tarmo 2008-09-10 Support :limit on update_al... 895 end
896
0e0866e0 » Emilio Tagua 2009-07-21 Introduced ActiveRecord::Re... 897 relation.update(sanitize_sql_for_assignment(updates))
db045dbb » dhh 2004-11-23 Initial 898 end
0d2db8a7 » dhh 2005-01-24 Added Base.update_collectio... 899
39e1ac65 » lifo 2009-01-18 Merge docrails 900 # Destroys the records matching +conditions+ by instantiating each
901 # record and calling its +destroy+ method. Each object's callbacks are
902 # executed (including <tt>:dependent</tt> association options and
903 # +before_destroy+/+after_destroy+ Observer methods). Returns the
904 # collection of objects that were destroyed; each will be frozen, to
905 # reflect that no changes should be made (since they can't be
906 # persisted).
907 #
908 # Note: Instantiation, callback execution, and deletion of each
909 # record can be time consuming when you're removing many records at
910 # once. It generates at least one SQL +DELETE+ query per record (or
911 # possibly more, to enforce your callbacks). If you want to delete many
912 # rows quickly, without concern for their associations or callbacks, use
913 # +delete_all+ instead.
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 914 #
a2932784 » lifo 2008-10-05 Merge docrails 915 # ==== Parameters
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 916 #
39e1ac65 » lifo 2009-01-18 Merge docrails 917 # * +conditions+ - A string, array, or hash that specifies which records
918 # to destroy. If omitted, all records are destroyed. See the
919 # Conditions section in the introduction to ActiveRecord::Base for
920 # more information.
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 921 #
39e1ac65 » lifo 2009-01-18 Merge docrails 922 # ==== Examples
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 923 #
a2932784 » lifo 2008-10-05 Merge docrails 924 # Person.destroy_all("last_login < '2004-04-04'")
39e1ac65 » lifo 2009-01-18 Merge docrails 925 # Person.destroy_all(:status => "inactive")
db045dbb » dhh 2004-11-23 Initial 926 def destroy_all(conditions = nil)
3dfa56cc » dhh 2005-06-26 Updated all references to t... 927 find(:all, :conditions => conditions).each { |object| object.destroy }
db045dbb » dhh 2004-11-23 Initial 928 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 929
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 930 # Deletes the records matching +conditions+ without instantiating the records first, and hence not
6ef35461 » lifo 2008-09-03 Merge docrails 931 # calling the +destroy+ method nor invoking callbacks. This is a single SQL DELETE statement that
a2932784 » lifo 2008-10-05 Merge docrails 932 # goes straight to the database, much more efficient than +destroy_all+. Be careful with relations
53cd102b » lifo 2009-02-24 Merge with docrails 933 # though, in particular <tt>:dependent</tt> rules defined on associations are not honored. Returns
934 # the number of rows affected.
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 935 #
a2932784 » lifo 2008-10-05 Merge docrails 936 # ==== Parameters
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 937 #
dc4eec11 » lifo 2008-05-09 Merge docrails: 938 # * +conditions+ - Conditions are specified the same way as with +find+ method.
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 939 #
940 # ==== Example
941 #
a2932784 » lifo 2008-10-05 Merge docrails 942 # Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')")
943 # Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else'])
4b055a4a » jeremy 2007-12-10 Update destroy_all and dele... 944 #
a2932784 » lifo 2008-10-05 Merge docrails 945 # Both calls delete the affected posts all at once with a single DELETE statement. If you need to destroy dependent
6ef35461 » lifo 2008-09-03 Merge docrails 946 # associations or call your <tt>before_*</tt> or +after_destroy+ callbacks, use the +destroy_all+ method instead.
db045dbb » dhh 2004-11-23 Initial 947 def delete_all(conditions = nil)
52271195 » Emilio Tagua 2009-06-02 Refactors to work with late... 948 if conditions
66fbcc1d » Emilio Tagua 2009-08-18 Use immutable relation obje... 949 arel_table.conditions(Arel::SqlLiteral.new(construct_conditions(conditions, scope(:find)))).delete
52271195 » Emilio Tagua 2009-06-02 Refactors to work with late... 950 else
951 arel_table.delete
952 end
db045dbb » dhh 2004-11-23 Initial 953 end
954
955 # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
73673256 » jeremy 2007-12-09 Document Active Record exce... 956 # The use of this method should be restricted to complicated SQL queries that can't be executed
ee614d63 » Marcel Molina 2007-05-05 Add documentation caveat ab... 957 # using the ActiveRecord::Calculations class methods. Look into those before using this.
958 #
a2932784 » lifo 2008-10-05 Merge docrails 959 # ==== Parameters
73673256 » jeremy 2007-12-09 Document Active Record exce... 960 #
dc4eec11 » lifo 2008-05-09 Merge docrails: 961 # * +sql+ - An SQL statement which should return a count query from the database, see the example below.
ee614d63 » Marcel Molina 2007-05-05 Add documentation caveat ab... 962 #
963 # ==== Examples
964 #
e17bf818 » jamis 2005-08-14 Fix typo in count_by_sql do... 965 # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
db045dbb » dhh 2004-11-23 Initial 966 def count_by_sql(sql)
a775cb19 » dhh 2004-12-07 Added the option for saniti... 967 sql = sanitize_conditions(sql)
caaf40d5 » dhh 2005-09-24 Added AbstractAdapter#selec... 968 connection.select_value(sql, "#{name} Count").to_i
db045dbb » dhh 2004-11-23 Initial 969 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 970
83752373 » jamis 2007-02-07 Made increment_counter/decr... 971 # A generic "counter updater" implementation, intended primarily to be
972 # used by increment_counter and decrement_counter, but which may also
973 # be useful on its own. It simply does a direct SQL update for the record
974 # with the given ID, altering the given hash of counters by the amount
975 # given by the corresponding value:
976 #
a2932784 » lifo 2008-10-05 Merge docrails 977 # ==== Parameters
73673256 » jeremy 2007-12-09 Document Active Record exce... 978 #
74871961 » lifo 2009-01-28 Add array id support to Mod... 979 # * +id+ - The id of the object you wish to update a counter on or an Array of ids.
dc4eec11 » lifo 2008-05-09 Merge docrails: 980 # * +counters+ - An Array of Hashes containing the names of the fields
981 # to update as keys and the amount to update the field by as values.
73673256 » jeremy 2007-12-09 Document Active Record exce... 982 #
6bd7d30e » Marcel Molina 2007-12-05 Document options for update... 983 # ==== Examples
73673256 » jeremy 2007-12-09 Document Active Record exce... 984 #
985 # # For the Post with id of 5, decrement the comment_count by 1, and
6bd7d30e » Marcel Molina 2007-12-05 Document options for update... 986 # # increment the action_count by 1
83752373 » jamis 2007-02-07 Made increment_counter/decr... 987 # Post.update_counters 5, :comment_count => -1, :action_count => 1
6bd7d30e » Marcel Molina 2007-12-05 Document options for update... 988 # # Executes the following SQL:
83752373 » jamis 2007-02-07 Made increment_counter/decr... 989 # # UPDATE posts
990 # # SET comment_count = comment_count - 1,
991 # # action_count = action_count + 1
992 # # WHERE id = 5
74871961 » lifo 2009-01-28 Add array id support to Mod... 993 #
994 # # For the Posts with id of 10 and 15, increment the comment_count by 1
995 # Post.update_counters [10, 15], :comment_count => 1
996 # # Executes the following SQL:
997 # # UPDATE posts
998 # # SET comment_count = comment_count + 1,
999 # # WHERE id IN (10, 15)
83752373 » jamis 2007-02-07 Made increment_counter/decr... 1000 def update_counters(id, counters)
1001 updates = counters.inject([]) { |list, (counter_name, increment)|
1002 sign = increment < 0 ? "-" : "+"
459e5817 » miloops 2008-06-26 update_counters should upda... 1003 list << "#{connection.quote_column_name(counter_name)} = COALESCE(#{connection.quote_column_name(counter_name)}, 0) #{sign} #{increment.abs}"
83752373 » jamis 2007-02-07 Made increment_counter/decr... 1004 }.join(", ")
74871961 » lifo 2009-01-28 Add array id support to Mod... 1005
1006 if id.is_a?(Array)
1007 ids_list = id.map {|i| quote_value(i)}.join(', ')
1008 condition = "IN (#{ids_list})"
1009 else
1010 condition = "= #{quote_value(id)}"
1011 end
1012
1013 update_all(updates, "#{connection.quote_column_name(primary_key)} #{condition}")
83752373 » jamis 2007-02-07 Made increment_counter/decr... 1014 end
1015
15dc567e » Marcel Molina 2007-05-05 Also add documentation enha... 1016 # Increment a number field by one, usually representing a count.
1017 #
73673256 » jeremy 2007-12-09 Document Active Record exce... 1018 # This is used for caching aggregate values, so that they don't need to be computed every time.
1019 # For example, a DiscussionBoard may cache post_count and comment_count otherwise every time the board is
7143d801 » Marcel Molina 2007-11-07 Smattering of grammatical f... 1020 # shown it would have to run an SQL query to find how many posts and comments there are.
15dc567e » Marcel Molina 2007-05-05 Also add documentation enha... 1021 #
a2932784 » lifo 2008-10-05 Merge docrails 1022 # ==== Parameters
15dc567e » Marcel Molina 2007-05-05 Also add documentation enha... 1023 #
dc4eec11 » lifo 2008-05-09 Merge docrails: 1024 # * +counter_name+ - The name of the field that should be incremented.
1025 # * +id+ - The id of the object that should be incremented.
15dc567e » Marcel Molina 2007-05-05 Also add documentation enha... 1026 #
1027 # ==== Examples
1028 #
1029 # # Increment the post_count column for the record with an id of 5
1030 # DiscussionBoard.increment_counter(:post_count, 5)
db045dbb » dhh 2004-11-23 Initial 1031 def increment_counter(counter_name, id)
83752373 » jamis 2007-02-07 Made increment_counter/decr... 1032 update_counters(id, counter_name => 1)
db045dbb » dhh 2004-11-23 Initial 1033 end
1034
5bd35705 » Marcel Molina 2007-05-05 Enhance documentation for d... 1035 # Decrement a number field by one, usually representing a count.
1036 #
1037 # This works the same as increment_counter but reduces the column value by 1 instead of increasing it.
1038 #
a2932784 » lifo 2008-10-05 Merge docrails 1039 # ==== Parameters
5bd35705 » Marcel Molina 2007-05-05 Enhance documentation for d... 1040 #
dc4eec11 » lifo 2008-05-09 Merge docrails: 1041 # * +counter_name+ - The name of the field that should be decremented.
1042 # * +id+ - The id of the object that should be decremented.
5bd35705 » Marcel Molina 2007-05-05 Enhance documentation for d... 1043 #
1044 # ==== Examples
1045 #
1046 # # Decrement the post_count column for the record with an id of 5
1047 # DiscussionBoard.decrement_counter(:post_count, 5)
db045dbb » dhh 2004-11-23 Initial 1048 def decrement_counter(counter_name, id)
83752373 » jamis 2007-02-07 Made increment_counter/decr... 1049 update_counters(id, counter_name => -1)
db045dbb » dhh 2004-11-23 Initial 1050 end
1051
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1052 # Attributes named in this macro are protected from mass-assignment,
1053 # such as <tt>new(attributes)</tt>,
1054 # <tt>update_attributes(attributes)</tt>, or
1055 # <tt>attributes=(attributes)</tt>.
1056 #
1057 # Mass-assignment to these attributes will simply be ignored, to assign
1058 # to them you can use direct writer methods. This is meant to protect
1059 # sensitive attributes from being overwritten by malicious users
1060 # tampering with URLs or forms.
db045dbb » dhh 2004-11-23 Initial 1061 #
1062 # class Customer < ActiveRecord::Base
1063 # attr_protected :credit_rating
1064 # end
1065 #
1066 # customer = Customer.new("name" => David, "credit_rating" => "Excellent")
1067 # customer.credit_rating # => nil
1068 # customer.attributes = { "description" => "Jolly fellow", "credit_rating" => "Superb" }
1069 # customer.credit_rating # => nil
1070 #
1071 # customer.credit_rating = "Average"
1072 # customer.credit_rating # => "Average"
d761ac40 » Marcel Molina 2007-10-25 Add docs explaining how to ... 1073 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1074 # To start from an all-closed default and enable attributes as needed,
1075 # have a look at +attr_accessible+.
e033b5d0 » lifo 2009-07-25 Merge docrails 1076 #
1077 # If the access logic of your application is richer you can use <tt>Hash#except</tt>
1078 # or <tt>Hash#slice</tt> to sanitize the hash of parameters before they are
1079 # passed to Active Record.
31c83534 » Emilio Tagua 2009-08-03 Don't use local vars before... 1080 #
e033b5d0 » lifo 2009-07-25 Merge docrails 1081 # For example, it could be the case that the list of protected attributes
1082 # for a given model depends on the role of the user:
1083 #
1084 # # Assumes plan_id is not protected because it depends on the role.
1085 # params[:account] = params[:account].except(:plan_id) unless admin?
1086 # @account.update_attributes(params[:account])
1087 #
1088 # Note that +attr_protected+ is still applied to the received hash. Thus,
1089 # with this technique you can at most _extend_ the list of protected
1090 # attributes for a particular mass-assignment call.
db045dbb » dhh 2004-11-23 Initial 1091 def attr_protected(*attributes)
b6bac73b » carlhuda 2009-05-14 Merge commit 'origin/master' 1092 write_inheritable_attribute(:attr_protected, Set.new(attributes.map {|a| a.to_s}) + (protected_attributes || []))
db045dbb » dhh 2004-11-23 Initial 1093 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 1094
098fa943 » dhh 2005-02-07 Fixed documentation snafus ... 1095 # Returns an array of all the attributes that have been protected from mass-assignment.
db045dbb » dhh 2004-11-23 Initial 1096 def protected_attributes # :nodoc:
288e947a » clemens 2008-09-02 Some performance goodness f... 1097 read_inheritable_attribute(:attr_protected)
db045dbb » dhh 2004-11-23 Initial 1098 end
1099
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1100 # Specifies a white list of model attributes that can be set via
1101 # mass-assignment, such as <tt>new(attributes)</tt>,
1102 # <tt>update_attributes(attributes)</tt>, or
1103 # <tt>attributes=(attributes)</tt>
f770b829 » Marcel Molina 2007-11-06 Enhance explanation with mo... 1104 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1105 # This is the opposite of the +attr_protected+ macro: Mass-assignment
1106 # will only set attributes in this list, to assign to the rest of
1107 # attributes you can use direct writer methods. This is meant to protect
1108 # sensitive attributes from being overwritten by malicious users
1109 # tampering with URLs or forms. If you'd rather start from an all-open
1110 # default and restrict attributes as needed, have a look at
1111 # +attr_protected+.
d761ac40 » Marcel Molina 2007-10-25 Add docs explaining how to ... 1112 #
1113 # class Customer < ActiveRecord::Base
f770b829 » Marcel Molina 2007-11-06 Enhance explanation with mo... 1114 # attr_accessible :name, :nickname
d761ac40 » Marcel Molina 2007-10-25 Add docs explaining how to ... 1115 # end
1116 #
f770b829 » Marcel Molina 2007-11-06 Enhance explanation with mo... 1117 # customer = Customer.new(:name => "David", :nickname => "Dave", :credit_rating => "Excellent")
1118 # customer.credit_rating # => nil
1119 # customer.attributes = { :name => "Jolly fellow", :credit_rating => "Superb" }
1120 # customer.credit_rating # => nil
d761ac40 » Marcel Molina 2007-10-25 Add docs explaining how to ... 1121 #
f770b829 » Marcel Molina 2007-11-06 Enhance explanation with mo... 1122 # customer.credit_rating = "Average"
1123 # customer.credit_rating # => "Average"
e033b5d0 » lifo 2009-07-25 Merge docrails 1124 #
1125 # If the access logic of your application is richer you can use <tt>Hash#except</tt>
1126 # or <tt>Hash#slice</tt> to sanitize the hash of parameters before they are
1127 # passed to Active Record.
31c83534 » Emilio Tagua 2009-08-03 Don't use local vars before... 1128 #
e033b5d0 » lifo 2009-07-25 Merge docrails 1129 # For example, it could be the case that the list of accessible attributes
1130 # for a given model depends on the role of the user:
1131 #
1132 # # Assumes plan_id is accessible because it depends on the role.
1133 # params[:account] = params[:account].except(:plan_id) unless admin?
1134 # @account.update_attributes(params[:account])
1135 #
1136 # Note that +attr_accessible+ is still applied to the received hash. Thus,
1137 # with this technique you can at most _narrow_ the list of accessible
1138 # attributes for a particular mass-assignment call.
db045dbb » dhh 2004-11-23 Initial 1139 def attr_accessible(*attributes)
288e947a » clemens 2008-09-02 Some performance goodness f... 1140 write_inheritable_attribute(:attr_accessible, Set.new(attributes.map(&:to_s)) + (accessible_attributes || []))
db045dbb » dhh 2004-11-23 Initial 1141 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 1142
098fa943 » dhh 2005-02-07 Fixed documentation snafus ... 1143 # Returns an array of all the attributes that have been made accessible to mass-assignment.
db045dbb » dhh 2004-11-23 Initial 1144 def accessible_attributes # :nodoc:
288e947a » clemens 2008-09-02 Some performance goodness f... 1145 read_inheritable_attribute(:attr_accessible)
db045dbb » dhh 2004-11-23 Initial 1146 end
1147
66d05f5e » technoweenie 2007-09-30 Add attr_readonly to specif... 1148 # Attributes listed as readonly can be set for a new record, but will be ignored in database updates afterwards.
1149 def attr_readonly(*attributes)
288e947a » clemens 2008-09-02 Some performance goodness f... 1150 write_inheritable_attribute(:attr_readonly, Set.new(attributes.map(&:to_s)) + (readonly_attributes || []))
66d05f5e » technoweenie 2007-09-30 Add attr_readonly to specif... 1151 end
1152
1153 # Returns an array of all the attributes that have been specified as readonly.
1154 def readonly_attributes
5b61168a » Emilio Tagua 2009-04-30 Added arel_attributes_value... 1155 read_inheritable_attribute(:attr_readonly) || []
66d05f5e » technoweenie 2007-09-30 Add attr_readonly to specif... 1156 end
c450a36f » dhh 2006-03-05 Doc fixes 1157
73673256 » jeremy 2007-12-09 Document Active Record exce... 1158 # If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object,
1159 # then specify the name of that attribute using this method and it will be handled automatically.
1160 # The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1161 # class on retrieval or SerializationTypeMismatch will be raised.
1a0cdf74 » dhh 2007-06-23 Docfix (closes #8096) 1162 #
a2932784 » lifo 2008-10-05 Merge docrails 1163 # ==== Parameters
1a0cdf74 » dhh 2007-06-23 Docfix (closes #8096) 1164 #
dc4eec11 » lifo 2008-05-09 Merge docrails: 1165 # * +attr_name+ - The field name that should be serialized.
1166 # * +class_name+ - Optional, class name that the object type should be equal to.
1a0cdf74 » dhh 2007-06-23 Docfix (closes #8096) 1167 #
1168 # ==== Example
1169 # # Serialize a preferences attribute
1170 # class User
1171 # serialize :preferences
1172 # end
db045dbb » dhh 2004-11-23 Initial 1173 def serialize(attr_name, class_name = Object)
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 1174 serialized_attributes[attr_name.to_s] = class_name
db045dbb » dhh 2004-11-23 Initial 1175 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 1176
db045dbb » dhh 2004-11-23 Initial 1177 # Returns a hash of all the attributes that have been specified for serialization as keys and their class restriction as values.
1178 def serialized_attributes
288e947a » clemens 2008-09-02 Some performance goodness f... 1179 read_inheritable_attribute(:attr_serialized) or write_inheritable_attribute(:attr_serialized, {})
db045dbb » dhh 2004-11-23 Initial 1180 end
1181
1182 # Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1183 # directly from ActiveRecord::Base. So if the hierarchy looks like: Reply < Message < ActiveRecord::Base, then Message is used
d64832c0 » Marcel Molina 2007-12-05 Give examples for what tabl... 1184 # to guess the table name even when called on Reply. The rules used to do the guess are handled by the Inflector class
7143d801 » Marcel Molina 2007-11-07 Smattering of grammatical f... 1185 # in Active Support, which knows almost all common English inflections. You can add new inflections in config/initializers/inflections.rb.
db045dbb » dhh 2004-11-23 Initial 1186 #
14101c7b » jeremy 2006-08-16 Nested classes are given ta... 1187 # Nested classes are given table names prefixed by the singular form of
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1188 # the parent's table name. Enclosing modules are not considered.
1189 #
1190 # ==== Examples
d64832c0 » Marcel Molina 2007-12-05 Give examples for what tabl... 1191 #
1192 # class Invoice < ActiveRecord::Base; end;
14101c7b » jeremy 2006-08-16 Nested classes are given ta... 1193 # file class table_name
1194 # invoice.rb Invoice invoices
d64832c0 » Marcel Molina 2007-12-05 Give examples for what tabl... 1195 #
1196 # class Invoice < ActiveRecord::Base; class Lineitem < ActiveRecord::Base; end; end;
1197 # file class table_name
1198 # invoice.rb Invoice::Lineitem invoice_lineitems
1199 #
1200 # module Invoice; class Lineitem < ActiveRecord::Base; end; end;
1201 # file class table_name
1202 # invoice/lineitem.rb Invoice::Lineitem lineitems
db045dbb » dhh 2004-11-23 Initial 1203 #
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1204 # Additionally, the class-level +table_name_prefix+ is prepended and the
1205 # +table_name_suffix+ is appended. So if you have "myapp_" as a prefix,
14101c7b » jeremy 2006-08-16 Nested classes are given ta... 1206 # the table name guess for an Invoice class becomes "myapp_invoices".
1207 # Invoice::Lineitem becomes "myapp_invoice_lineitems".
1208 #
1209 # You can also overwrite this class method to allow for unguessable
1210 # links, such as a Mouse class with a link to a "mice" table. Example:
db045dbb » dhh 2004-11-23 Initial 1211 #
1212 # class Mouse < ActiveRecord::Base
14101c7b » jeremy 2006-08-16 Nested classes are given ta... 1213 # set_table_name "mice"
db045dbb » dhh 2004-11-23 Initial 1214 # end
dcc48680 » dhh 2004-12-22 Fixed that Base.table_name ... 1215 def table_name
d736568f » Marcel Molina 2005-10-10 Speed up the setting of tab... 1216 reset_table_name
1217 end
1218
fed7d334 » dhh 2006-03-27 Fixed documentation 1219 def reset_table_name #:nodoc:
bcbce90b » jeremy 2006-08-25 Nested subclasses are not p... 1220 base = base_class
1221
1222 name =
1223 # STI subclasses always use their superclass' table.
1224 unless self == base
1225 base.table_name
1226 else
1227 # Nested classes are prefixed with singular parent table name.
1228 if parent < ActiveRecord::Base && !parent.abstract_class?
1229 contained = parent.table_name
1230 contained = contained.singularize if parent.pluralize_table_names
1231 contained << '_'
1232 end
1233 name = "#{table_name_prefix}#{contained}#{undecorated_table_name(base.name)}#{table_name_suffix}"
1234 end
1235
c450a36f » dhh 2006-03-05 Doc fixes 1236 set_table_name(name)
d736568f » Marcel Molina 2005-10-10 Speed up the setting of tab... 1237 name
db045dbb » dhh 2004-11-23 Initial 1238 end
1239
9d2da046 » jeremy 2006-11-09 Cache inheritance_column. C... 1240 # Defines the column name for use with single table inheritance
1241 # -- can be set in subclasses like so: self.inheritance_column = "type_id"
db045dbb » dhh 2004-11-23 Initial 1242 def inheritance_column
9d2da046 » jeremy 2006-11-09 Cache inheritance_column. C... 1243 @inheritance_column ||= "type".freeze
db045dbb » dhh 2004-11-23 Initial 1244 end
1245
7c8f3edc » jeremy 2005-11-12 r4325@asus: jeremy | 2005... 1246 # Lazy-set the sequence name to the connection's default. This method
1247 # is only ever called once since set_sequence_name overrides it.
fed7d334 » dhh 2006-03-27 Fixed documentation 1248 def sequence_name #:nodoc:
7c8f3edc » jeremy 2005-11-12 r4325@asus: jeremy | 2005... 1249 reset_sequence_name
1250 end
1251
fed7d334 » dhh 2006-03-27 Fixed documentation 1252 def reset_sequence_name #:nodoc:
7c8f3edc » jeremy 2005-11-12 r4325@asus: jeremy | 2005... 1253 default = connection.default_sequence_name(table_name, primary_key)
1254 set_sequence_name(default)
1255 default
14ea3128 » dhh 2005-07-24 Made Oracle a first-class c... 1256 end
1257
1aa82b32 » dhh 2005-02-07 Added keyword-style approac... 1258 # Sets the table name to use to the given value, or (if the value
4eab3758 » dhh 2005-02-23 Finished polishing API docs 1259 # is nil or false) to the value returned by the given block.
1aa82b32 » dhh 2005-02-07 Added keyword-style approac... 1260 #
1261 # class Project < ActiveRecord::Base
1262 # set_table_name "project"
1263 # end
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1264 def set_table_name(value = nil, &block)
1aa82b32 » dhh 2005-02-07 Added keyword-style approac... 1265 define_attr_method :table_name, value, &block
1266 end
1267 alias :table_name= :set_table_name
1268
1269 # Sets the name of the inheritance column to use to the given value,
1270 # or (if the value # is nil or false) to the value returned by the
4eab3758 » dhh 2005-02-23 Finished polishing API docs 1271 # given block.
1aa82b32 » dhh 2005-02-07 Added keyword-style approac... 1272 #
1273 # class Project < ActiveRecord::Base
1274 # set_inheritance_column do
1275 # original_inheritance_column + "_id"
1276 # end
1277 # end
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1278 def set_inheritance_column(value = nil, &block)
1aa82b32 » dhh 2005-02-07 Added keyword-style approac... 1279 define_attr_method :inheritance_column, value, &block
1280 end
1281 alias :inheritance_column= :set_inheritance_column
1282
14ea3128 » dhh 2005-07-24 Made Oracle a first-class c... 1283 # Sets the name of the sequence to use when generating ids to the given
1284 # value, or (if the value is nil or false) to the value returned by the
7117fdb8 » jeremy 2005-10-15 r3616@asus: jeremy | 2005... 1285 # given block. This is required for Oracle and is useful for any
1286 # database which relies on sequences for primary key generation.
14ea3128 » dhh 2005-07-24 Made Oracle a first-class c... 1287 #
2076dca6 » jeremy 2005-11-16 r3095@asus: jeremy | 2005... 1288 # If a sequence name is not explicitly set when using Oracle or Firebird,
1289 # it will default to the commonly used pattern of: #{table_name}_seq
1290 #
1291 # If a sequence name is not explicitly set when using PostgreSQL, it
1292 # will discover the sequence corresponding to your primary key for you.
14ea3128 » dhh 2005-07-24 Made Oracle a first-class c... 1293 #
1294 # class Project < ActiveRecord::Base
1295 # set_sequence_name "projectseq" # default would have been "project_seq"
1296 # end
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1297 def set_sequence_name(value = nil, &block)
14ea3128 » dhh 2005-07-24 Made Oracle a first-class c... 1298 define_attr_method :sequence_name, value, &block
1299 end
1300 alias :sequence_name= :set_sequence_name
1301
db045dbb » dhh 2004-11-23 Initial 1302 # Turns the +table_name+ back into a class name following the reverse rules of +table_name+.
1303 def class_name(table_name = table_name) # :nodoc:
1304 # remove any prefix and/or suffix from the table name
81737fc0 » jeremy 2005-07-03 r1613@asus: jeremy | 2005... 1305 class_name = table_name[table_name_prefix.length..-(table_name_suffix.length + 1)].camelize
1306 class_name = class_name.singularize if pluralize_table_names
1307 class_name
db045dbb » dhh 2004-11-23 Initial 1308 end
1309
816f37a2 » dhh 2005-10-28 Added migration support to ... 1310 # Indicates whether the table associated with this class exists
1311 def table_exists?
8877ab58 » tarmo 2008-05-06 Added AbstractAdapter#table... 1312 connection.table_exists?(table_name)
816f37a2 » dhh 2005-10-28 Added migration support to ... 1313 end
1314
db045dbb » dhh 2004-11-23 Initial 1315 # Returns an array of column objects for the table associated with this class.
1316 def columns
8b5f4e47 » jeremy 2007-12-22 Ruby 1.9 compat: fix warnin... 1317 unless defined?(@columns) && @columns
c0899bca » Marcel Molina 2005-10-06 Add convenience predicate m... 1318 @columns = connection.columns(table_name, "#{name} Columns")
8b5f4e47 » jeremy 2007-12-22 Ruby 1.9 compat: fix warnin... 1319 @columns.each { |column| column.primary = column.name == primary_key }
c0899bca » Marcel Molina 2005-10-06 Add convenience predicate m... 1320 end
1321 @columns
db045dbb » dhh 2004-11-23 Initial 1322 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 1323
3b4450bb » NZKoz 2006-12-27 Docs fix for columns_hash [... 1324 # Returns a hash of column objects for the table associated with this class.
db045dbb » dhh 2004-11-23 Initial 1325 def columns_hash
1326 @columns_hash ||= columns.inject({}) { |hash, column| hash[column.name] = column; hash }
1327 end
d0bd3b5a » jeremy 2005-06-11 Return PostgreSQL columns i... 1328
fed7d334 » dhh 2006-03-27 Fixed documentation 1329 # Returns an array of column names as strings.
49d0f0cb » dhh 2005-04-18 Speeded up eager loading a ... 1330 def column_names
d0bd3b5a » jeremy 2005-06-11 Return PostgreSQL columns i... 1331 @column_names ||= columns.map { |column| column.name }
49d0f0cb » dhh 2005-04-18 Speeded up eager loading a ... 1332 end
db045dbb » dhh 2004-11-23 Initial 1333
2948910b » Marcel Molina 2005-10-10 Misc doc fixes (typos/gramm... 1334 # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
1335 # and columns used for single table inheritance have been removed.
db045dbb » dhh 2004-11-23 Initial 1336 def content_columns
c0899bca » Marcel Molina 2005-10-06 Add convenience predicate m... 1337 @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
db045dbb » dhh 2004-11-23 Initial 1338 end
1339
1340 # Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key
1341 # and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 1342 # is available.
fed7d334 » dhh 2006-03-27 Fixed documentation 1343 def column_methods_hash #:nodoc:
d0bd3b5a » jeremy 2005-06-11 Return PostgreSQL columns i... 1344 @dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr|
3ab3a70b » jeremy 2005-10-22 Clarify semantics of Active... 1345 attr_name = attr.to_s
1346 methods[attr.to_sym] = attr_name
1347 methods["#{attr}=".to_sym] = attr_name
1348 methods["#{attr}?".to_sym] = attr_name
1349 methods["#{attr}_before_type_cast".to_sym] = attr_name
db045dbb » dhh 2004-11-23 Initial 1350 methods
1351 end
1352 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 1353
a2932784 » lifo 2008-10-05 Merge docrails 1354 # Resets all the cached information about columns, which will cause them
1355 # to be reloaded on the next request.
1356 #
1357 # The most common usage pattern for this method is probably in a migration,
1358 # when just after creating a table you want to populate it with some default
1359 # values, eg:
1360 #
1361 # class CreateJobLevels < ActiveRecord::Migration
1362 # def self.up
1363 # create_table :job_levels do |t|
1364 # t.integer :id
1365 # t.string :name
1366 #
1367 # t.timestamps
1368 # end
1369 #
1370 # JobLevel.reset_column_information
1371 # %w{assistant executive manager director}.each do |type|
1372 # JobLevel.create(:name => type)
1373 # end
1374 # end
1375 #
1376 # def self.down
1377 # drop_table :job_levels
1378 # end
1379 # end
1314f48d » dhh 2004-12-12 Added methods for resetting... 1380 def reset_column_information
e129c567 » josh 2009-07-29 Wrap up attribute method re... 1381 undefine_attribute_methods
d56e9877 » Emilio Tagua 2009-08-27 No need to reload the relat... 1382 @arel_table = @column_names = @columns = @columns_hash = @content_columns = @dynamic_methods_hash = @inheritance_column = nil
1314f48d » dhh 2004-12-12 Added methods for resetting... 1383 end
1384
4eab3758 » dhh 2005-02-23 Finished polishing API docs 1385 def reset_column_information_and_inheritable_attributes_for_all_subclasses#:nodoc:
1314f48d » dhh 2004-12-12 Added methods for resetting... 1386 subclasses.each { |klass| klass.reset_inheritable_attributes; klass.reset_column_information }
1387 end
db045dbb » dhh 2004-11-23 Initial 1388
3c64c9a5 » chrisk 2009-03-12 Fix spelling of an internal... 1389 def self_and_descendants_from_active_record#nodoc:
ffeab4e0 » iain 2008-08-13 Cleaned up ActiveRecord i18... 1390 klass = self
1391 classes = [klass]
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1392 while klass != klass.base_class
ffeab4e0 » iain 2008-08-13 Cleaned up ActiveRecord i18... 1393 classes << klass = klass.superclass
1394 end
1395 classes
1396 rescue
1397 # OPTIMIZE this rescue is to fix this test: ./test/cases/reflection_test.rb:56:in `test_human_name_for_column'
e033b5d0 » lifo 2009-07-25 Merge docrails 1398 # Apparently the method base_class causes some trouble.
ffeab4e0 » iain 2008-08-13 Cleaned up ActiveRecord i18... 1399 # It now works for sure.
1400 [self]
1401 end
1402
db045dbb » dhh 2004-11-23 Initial 1403 # Transforms attribute key names into a more humane format, such as "First name" instead of "first_name". Example:
1404 # Person.human_attribute_name("first_name") # => "First name"
e033b5d0 » lifo 2009-07-25 Merge docrails 1405 # This used to be deprecated in favor of humanize, but is now preferred, because it automatically uses the I18n
ffeab4e0 » iain 2008-08-13 Cleaned up ActiveRecord i18... 1406 # module now.
1407 # Specify +options+ with additional translating options.
1408 def human_attribute_name(attribute_key_name, options = {})
3c64c9a5 » chrisk 2009-03-12 Fix spelling of an internal... 1409 defaults = self_and_descendants_from_active_record.map do |klass|
ffeab4e0 » iain 2008-08-13 Cleaned up ActiveRecord i18... 1410 :"#{klass.name.underscore}.#{attribute_key_name}"
1411 end
1412 defaults << options[:default] if options[:default]
1413 defaults.flatten!
ce2422ce » arthurgeek 2009-08-09 Model#human_attribute_name ... 1414 defaults << attribute_key_name.to_s.humanize
ffeab4e0 » iain 2008-08-13 Cleaned up ActiveRecord i18... 1415 options[:count] ||= 1
1416 I18n.translate(defaults.shift, options.merge(:default => defaults, :scope => [:activerecord, :attributes]))
db045dbb » dhh 2004-11-23 Initial 1417 end
81e14fad » iain 2008-08-16 Added Base.human_name method 1418
1419 # Transform the modelname into a more humane format, using I18n.
7d548f79 » justinfrench 2009-06-29 Changed ActiveRecord::Base.... Comment 1420 # By default, it will underscore then humanize the class name (BlogPost.human_name #=> "Blog post").
81e14fad » iain 2008-08-16 Added Base.human_name method 1421 # Default scope of the translation is activerecord.models
1422 # Specify +options+ with additional translating options.
1423 def human_name(options = {})
3c64c9a5 » chrisk 2009-03-12 Fix spelling of an internal... 1424 defaults = self_and_descendants_from_active_record.map do |klass|
81e14fad » iain 2008-08-16 Added Base.human_name method 1425 :"#{klass.name.underscore}"
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1426 end
7d548f79 » justinfrench 2009-06-29 Changed ActiveRecord::Base.... Comment 1427 defaults << self.name.underscore.humanize
81e14fad » iain 2008-08-16 Added Base.human_name method 1428 I18n.translate(defaults.shift, {:scope => [:activerecord, :models], :count => 1, :default => defaults}.merge(options))
db045dbb » dhh 2004-11-23 Initial 1429 end
6e39c9e5 » jeremy 2005-07-03 r1614@asus: jeremy | 2005... 1430
06afb8c7 » jeremy 2007-01-22 Subclasses of an abstract c... 1431 # True if this isn't a concrete subclass needing a STI type condition.
1432 def descends_from_active_record?
1433 if superclass.abstract_class?
1434 superclass.descends_from_active_record?
1435 else
1436 superclass == Base || !columns_hash.include?(inheritance_column)
1437 end
db045dbb » dhh 2004-11-23 Initial 1438 end
1439
b4ec9904 » NZKoz 2007-10-02 Cache the descends_from_act... 1440 def finder_needs_type_condition? #:nodoc:
1441 # This is like this because benchmarking justifies the strange :false stuff
1442 :true == (@finder_needs_type_condition ||= descends_from_active_record? ? :false : :true)
1443 end
1444
d0360a4d » jeremy 2007-05-31 Base.inspect handles Base i... 1445 # Returns a string like 'Post id:integer, title:string, body:text'
52a9e508 » dhh 2007-04-21 Added ActiveRecord::Base.in... 1446 def inspect
d0360a4d » jeremy 2007-05-31 Base.inspect handles Base i... 1447 if self == Base
1448 super
1449 elsif abstract_class?
1450 "#{super}(abstract)"
bb94ce92 » NZKoz 2007-08-05 Let inspect on AR classes w... 1451 elsif table_exists?
d0360a4d » jeremy 2007-05-31 Base.inspect handles Base i... 1452 attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
1453 "#{super}(#{attr_list})"
bb94ce92 » NZKoz 2007-08-05 Let inspect on AR classes w... 1454 else
1455 "#{super}(Table doesn't exist)"
d0360a4d » jeremy 2007-05-31 Base.inspect handles Base i... 1456 end
52a9e508 » dhh 2007-04-21 Added ActiveRecord::Base.in... 1457 end
1458
b445ab98 » NZKoz 2006-09-04 Rename quote to quote_value... 1459 def quote_value(value, column = nil) #:nodoc:
b2c0ddf0 » Marcel Molina 2006-04-27 Add support for FrontBase (... 1460 connection.quote(value,column)
49403831 » dhh 2004-12-07 Fixed value quoting in all ... 1461 end
1462
7143d801 » Marcel Molina 2007-11-07 Smattering of grammatical f... 1463 # Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to <tt>connection.quote</tt>.
4eab3758 » dhh 2005-02-23 Finished polishing API docs 1464 def sanitize(object) #:nodoc:
49403831 » dhh 2004-12-07 Fixed value quoting in all ... 1465 connection.quote(object)
db045dbb » dhh 2004-11-23 Initial 1466 end
1467
97849deb » dhh 2005-01-23 Fixed that association prox... 1468 # Overwrite the default class equality method to provide support for association proxies.
1469 def ===(object)
1470 object.is_a?(self)
73673256 » jeremy 2007-12-09 Document Active Record exce... 1471 end
b840e4ed » Marcel Molina 2005-10-12 Deprecated ActiveRecord::Ba... 1472
d2f47503 » jamis 2006-01-20 Add AR::Base.base_class for... 1473 # Returns the base AR subclass that this class descends from. If A
1474 # extends AR::Base, A.base_class will return A. If B descends from A
1475 # through some arbitrarily deep hierarchy, B.base_class will return A.
1476 def base_class
1477 class_of_active_record_descendant(self)
1478 end
1479
98dc5827 » lifo 2008-05-25 Merge docrails. Comment 1480 # Set this to true if this is an abstract class (see <tt>abstract_class?</tt>).
def74603 » technoweenie 2006-03-15 Added Base.abstract_class? ... 1481 attr_accessor :abstract_class
1482
1483 # Returns whether this class is a base AR class. If A is a base class and
1484 # B descends from A, then B.base_class will return B.
1485 def abstract_class?
8b5f4e47 » jeremy 2007-12-22 Ruby 1.9 compat: fix warnin... 1486 defined?(@abstract_class) && @abstract_class == true
def74603 » technoweenie 2006-03-15 Added Base.abstract_class? ... 1487 end
1488
4f39382a » lifo 2008-04-06 Ensure that respond_to? con... 1489 def respond_to?(method_id, include_private = false)
143f5fbb » joshsusser 2008-08-25 refactor dynamic finder nam... 1490 if match = DynamicFinderMatch.match(method_id)
1491 return true if all_attributes_exists?(match.attribute_names)
66ee5890 » yaroslav 2008-12-28 Introduce dynamic scopes fo... Comment 1492 elsif match = DynamicScopeMatch.match(method_id)
1493 return true if all_attributes_exists?(match.attribute_names)
4f39382a » lifo 2008-04-06 Ensure that respond_to? con... 1494 end
c3aa2bcd » Manfred 2009-03-10 Ensure nested with_scope me... 1495
4f39382a » lifo 2008-04-06 Ensure that respond_to? con... 1496 super
1497 end
1498
72483c0d » technoweenie 2008-05-31 Add ActiveRecord::Base.sti_... 1499 def sti_name
1500 store_full_sti_class ? name : name.demodulize
1501 end
1502
e328bdaa » jeremy 2008-06-17 Make Base.merge_conditions ... 1503 # Merges conditions so that the result is a valid +condition+
1504 def merge_conditions(*conditions)
1505 segments = []
1506
1507 conditions.each do |condition|
1508 unless condition.blank?
1509 sql = sanitize_sql(condition)
1510 segments << sql unless sql.blank?
1511 end
1512 end
1513
1514 "(#{segments.join(') AND (')})" unless segments.empty?
1515 end
1516
f4a23567 » Emilio Tagua 2009-07-16 Added ActiveRecord::Base#(w... 1517
d56e9877 » Emilio Tagua 2009-08-27 No need to reload the relat... 1518 def arel_table(table = nil)
f4a23567 » Emilio Tagua 2009-07-16 Added ActiveRecord::Base#(w... 1519 table = table_name if table.blank?
d56e9877 » Emilio Tagua 2009-08-27 No need to reload the relat... 1520 if @arel_table.nil? || @arel_table.name != table
0d6997b6 » Emilio Tagua 2009-08-18 Cache #arel_able when possi... 1521 @arel_table = Relation.new(self, Arel::Table.new(table))
1522 end
1523 @arel_table
f4a23567 » Emilio Tagua 2009-07-16 Added ActiveRecord::Base#(w... 1524 end
1525
db045dbb » dhh 2004-11-23 Initial 1526 private
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1527 def find_initial(options)
361aaa04 » Aliaksey Kandratsenka 2008-01-15 Remove old :limit removal c... Comment 1528 options.update(:limit => 1)
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1529 find_every(options).first
1530 end
2fbe0ae7 » jeremy 2006-11-05 Support nil and Array in :c... 1531
d5a4d5ab » dhh 2008-03-12 Added ActiveRecord::Base.fi... 1532 def find_last(options)
1533 order = options[:order]
1534
1535 if order
1536 order = reverse_sql_order(order)
1537 elsif !scoped?(:find, :order)
1538 order = "#{table_name}.#{primary_key} DESC"
1539 end
1540
1541 if scoped?(:find, :order)
f7bd0beb » Daniel Luz 2008-12-21 Ensure Model#last doesn't a... 1542 scope = scope(:find)
1543 original_scoped_order = scope[:order]
1544 scope[:order] = reverse_sql_order(original_scoped_order)
d5a4d5ab » dhh 2008-03-12 Added ActiveRecord::Base.fi... 1545 end
3b0e1d90 » josh 2008-05-14 Prefer string core_ext infl... Comment 1546
f7bd0beb » Daniel Luz 2008-12-21 Ensure Model#last doesn't a... 1547 begin
1548 find_initial(options.merge({ :order => order }))
1549 ensure
1550 scope[:order] = original_scoped_order if original_scoped_order
1551 end
d5a4d5ab » dhh 2008-03-12 Added ActiveRecord::Base.fi... 1552 end
1553
1554 def reverse_sql_order(order_query)
5463823d » Emilio Tagua 2009-05-02 Remove unnecessary conditio... 1555 order_query.to_s.split(/,/).each { |s|
d5a4d5ab » dhh 2008-03-12 Added ActiveRecord::Base.fi... 1556 if s.match(/\s(asc|ASC)$/)
1557 s.gsub!(/\s(asc|ASC)$/, ' DESC')
1558 elsif s.match(/\s(desc|DESC)$/)
1559 s.gsub!(/\s(desc|DESC)$/, ' ASC')
5463823d » Emilio Tagua 2009-05-02 Remove unnecessary conditio... 1560 else
d5a4d5ab » dhh 2008-03-12 Added ActiveRecord::Base.fi... 1561 s.concat(' DESC')
1562 end
1563 }.join(',')
1564 end
3b0e1d90 » josh 2008-05-14 Prefer string core_ext infl... Comment 1565
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1566 def find_every(options)
355a8ff2 » jeremy 2008-01-18 Introduce preload query str... 1567 include_associations = merge_includes(scope(:find, :include), options[:include])
1568
1569 if include_associations.any? && references_eager_loaded_tables?(options)
1570 records = find_with_associations(options)
1571 else
1572 records = find_by_sql(construct_finder_sql(options))
1573 if include_associations.any?
1574 preload_associations(records, include_associations)
1575 end
1576 end
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1577
1578 records.each { |record| record.readonly! } if options[:readonly]
1579
1580 records
1581 end
2fbe0ae7 » jeremy 2006-11-05 Support nil and Array in :c... 1582
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1583 def find_from_ids(ids, options)
2fbe0ae7 » jeremy 2006-11-05 Support nil and Array in :c... 1584 expects_array = ids.first.kind_of?(Array)
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1585 return ids.first if expects_array && ids.first.empty?
2fbe0ae7 » jeremy 2006-11-05 Support nil and Array in :c... 1586
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1587 ids = ids.flatten.compact.uniq
1588
1589 case ids.size
1590 when 0
1591 raise RecordNotFound, "Couldn't find #{name} without an ID"
1592 when 1
1593 result = find_one(ids.first, options)
1594 expects_array ? [ result ] : result
1595 else
1596 find_some(ids, options)
1597 end
1598 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 1599
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1600 def find_one(id, options)
1601 conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 1602 options.update :conditions => "#{quoted_table_name}.#{connection.quote_column_name(primary_key)} = #{quote_value(id,columns_hash[primary_key])}#{conditions}"
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1603
230c5a06 » jeremy 2006-07-07 find_one uses find_every.fi... 1604 # Use find_every(options).first since the primary key condition
1605 # already ensures we have a single record. Using find_initial adds
1606 # a superfluous :limit => 1.
1607 if result = find_every(options).first
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1608 result
1609 else
1610 raise RecordNotFound, "Couldn't find #{name} with ID=#{id}#{conditions}"
1611 end
1612 end
73673256 » jeremy 2007-12-09 Document Active Record exce... 1613
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1614 def find_some(ids, options)
1615 conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
b445ab98 » NZKoz 2006-09-04 Rename quote to quote_value... 1616 ids_list = ids.map { |id| quote_value(id,columns_hash[primary_key]) }.join(',')
9b6207c3 » jeremy 2007-10-15 Quote table names. Defaults... 1617 options.update :conditions => "#{quoted_table_name}.#{connection.quote_column_name(primary_key)} IN (#{ids_list})#{conditions}"
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1618
1619 result = find_every(options)
1620
8158455d » jeremy 2007-05-31 Fix an edge case with find ... 1621 # Determine expected size from limit and offset, not just ids.size.
109926c5 » jeremy 2007-05-25 Find with a list of ids sup... 1622 expected_size =
1623 if options[:limit] && ids.size > options[:limit]
1624 options[:limit]
1625 else
1626 ids.size
1627 end
8158455d » jeremy 2007-05-31 Fix an edge case with find ... 1628
1629 # 11 ids with limit 3, offset 9 should give 2 results.
1630 if options[:offset] && (ids.size - options[:offset] < expected_size)
1631 expected_size = ids.size - options[:offset]
1632 end
109926c5 » jeremy 2007-05-25 Find with a list of ids sup... 1633
1634 if result.size == expected_size
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1635 result
1636 else
109926c5 » jeremy 2007-05-25 Find with a list of ids sup... 1637 raise RecordNotFound, "Couldn't find all #{name.pluralize} with IDs (#{ids_list})#{conditions} (found #{result.size} results, but was looking for #{expected_size})"
c9c18520 » dhh 2006-03-27 Making ActiveRecord faster ... 1638 end
1639 end
1640
4b4dd540 » jeremy 2006-08-23 Clashing type columns due t... 1641 # Finder methods must instantiate through this method to work with the
1642 # single-table inheritance model that makes it possible to create
1643 # objects of different types from the same table.
db045dbb » dhh 2004-11-23 Initial 1644 def instantiate(record)
3fc2d1eb » jeremy 2009-09-17 Extract class-finder method... 1645 object = find_sti_class(record[inheritance_column]).allocate
605bc775 » dhh 2004-12-14 Added a better exception fo... 1646
3fc2d1eb » jeremy 2009-09-17 Extract class-finder method... 1647 object.instance_variable_set(:'@attributes', record)
1648 object.instance_variable_set(:'@attributes_cache', {})
55efae23 » jeremy 2007-08-30 Performance: absorb instant... 1649
4f37b970 » josevalim 2009-09-08 Changed ActiveRecord to use... 1650 object.send(:_run_find_callbacks)
1651 object.send(:_run_initialize_callbacks)
55efae23 » jeremy 2007-08-30 Performance: absorb instant... 1652
81737fc0 » jeremy 2005-07-03 r1613@asus: jeremy | 2005... 1653 object
db045dbb » dhh 2004-11-23 Initial 1654 end
81737fc0 » jeremy 2005-07-03 r1613@asus: jeremy | 2005... 1655
3fc2d1eb » jeremy 2009-09-17 Extract class-finder method... 1656 def find_sti_class(type_name)
1657 if type_name.blank? || !columns_hash.include?(inheritance_column)
1658 self
1659 else
1660 begin
1661 compute_type(type_name)
1662 rescue NameError
1663 raise SubclassNotFound,
1664 "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " +
1665 "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
1666 "Please rename this column if you didn't intend it to be used for storing the inheritance class " +
1667 "or overwrite #{name}.inheritance_column to use another column for that information."
1668 end
1669 end
1670 end
1671
c7d6d68f » jeremy 2006-02-22 Reflections don't attempt t... 1672 # Nest the type name in the same module as this class.
1673 # Bar is "MyApp::Business::Bar" relative to MyApp::Business::Foo
db045dbb » dhh 2004-11-23 Initial 1674 def type_name_with_module(type_name)
72483c0d » technoweenie 2008-05-31 Add ActiveRecord::Base.sti_... 1675 if store_full_sti_class
1676 type_name
1677 else
1678 (/^::/ =~ type_name) ? type_name : "#{parent.name}::#{type_name}"
1679 end
db045dbb » dhh 2004-11-23 Initial 1680 end
1681
789a3f5b » willbryant 2008-11-13 Moved the * strings out of ... 1682 def default_select(qualified)
1683 if qualified
1684 quoted_table_name + '.*'
1685 else
1686 '*'
1687 end
1688 end
1689
0e0866e0 » Emilio Tagua 2009-07-21 Introduced ActiveRecord::Re... 1690 def construct_finder_arel(options = {}, scope = scope(:find))
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1691 # TODO add lock to Arel
6b67df70 » Emilio Tagua 2009-08-27 Revert "Revert "Add readonl... 1692 relation = arel_table(options[:from]).
66fbcc1d » Emilio Tagua 2009-08-18 Use immutable relation obje... 1693 joins(construct_join(options[:joins], scope)).
1694 conditions(construct_conditions(options[:conditions], scope)).
1695 select(options[:select] || (scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))).
1696 group(construct_group(options[:group], options[:having], scope)).
1697 order(construct_order(options[:order], scope)).
1698 limit(construct_limit(options[:limit], scope)).
1699 offset(construct_offset(options[:offset], scope))
6b67df70 » Emilio Tagua 2009-08-27 Revert "Revert "Add readonl... 1700
1701 relation = relation.readonly if options[:readonly]
1702
1703 relation
19d2ff83 » Emilio Tagua 2009-04-29 Calculations now use Arel t... 1704 end
1705
3b27a485 » Emilio Tagua 2009-06-23 Refactoring: Calculations n... 1706 def construct_finder_sql(options, scope = scope(:find))
0abba281 » Emilio Tagua 2009-08-18 Call to_sql method on Activ... 1707 construct_finder_arel(options, scope).to_sql
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1708 end
6abda696 » dhh 2005-12-02 Added preliminary support f... 1709
3e4452c7 » Emilio Tagua 2009-06-17 Forget about auto scope, it... 1710 def construct_join(joins, scope)
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1711 merged_joins = scope && scope[:joins] && joins ? merge_joins(scope[:joins], joins) : (joins || scope && scope[:joins])
1712 case merged_joins
1713 when Symbol, Hash, Array
1714 if array_of_strings?(merged_joins)
1715 merged_joins.join(' ') + " "
1716 else
9ac01fad » Emilio Tagua 2009-08-14 Use ARel's joins when build... 1717 build_association_joins(merged_joins)
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1718 end
1719 when String
1720 " #{merged_joins} "
19d2ff83 » Emilio Tagua 2009-04-29 Calculations now use Arel t... 1721 else
1722 ""
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1723 end
1724 end
1725
3e4452c7 » Emilio Tagua 2009-06-17 Forget about auto scope, it... 1726 def construct_group(group, having, scope)
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1727 sql = ''
1728 if group
1729 sql << group.to_s
1730 sql << " HAVING #{sanitize_sql_for_conditions(having)}" if having
f4a23567 » Emilio Tagua 2009-07-16 Added ActiveRecord::Base#(w... 1731 elsif scope && (scoped_group = scope[:group])
1732 sql << scoped_group.to_s
1733 sql << " HAVING #{sanitize_sql_for_conditions(scope[:having])}" if scope[:having]
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us... 1734 end
1735 sql
1736 end
6abda696 » dhh 2005-12-02 Added preliminary support f... 1737
3e4452c7 » Emilio Tagua 2009-06-17 Forget about auto scope, it... 1738 def construct_order(order, scope)
af9f9dd0 » Emilio Tagua 2009-06-10 Use array of orders instead... 1739 orders = []
09053960 » Emilio Tagua 2009-04-24 construct_finder_sql now us..