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