Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 721 lines (670 sloc) 29.775 kb
59f3218 @tenderlove load and prefer psych as the YAML parser when it is available
tenderlove authored
1 begin
2 require 'psych'
3 rescue LoadError
4 end
5
db045db @dhh Initial
dhh authored
6 require 'yaml'
aabf909 @jeremy Correct reader method generation for primary key attribute: handle case ...
jeremy authored
7 require 'set'
fab664a @jonleighton Fix another race condition.
jonleighton authored
8 require 'thread'
a15e02d @josevalim Unify benchmark APIs.
josevalim authored
9 require 'active_support/benchmarkable'
f5d720f @jeremy Opt in to Dependencies
jeremy authored
10 require 'active_support/dependencies'
033e0a0 @josevalim ActiveRecord and ActionPack now use the new descendants implementation.
josevalim authored
11 require 'active_support/descendants_tracker'
5f222c5 @jeremy Remove 'core' fluff. Hookable ActiveSupport.load_all!
jeremy authored
12 require 'active_support/time'
bab1f91 @phs table_name_prefix and table_name_suffix are class_attributes instead of ...
phs authored
13 require 'active_support/core_ext/class/attribute'
e8550ee @jeremy Cherry-pick core extensions
jeremy authored
14 require 'active_support/core_ext/class/attribute_accessors'
15 require 'active_support/core_ext/class/delegating_attributes'
d7db6a8 @joshk class inheritable attributes is used no more! all internal use of class ...
joshk authored
16 require 'active_support/core_ext/class/attribute'
e8550ee @jeremy Cherry-pick core extensions
jeremy authored
17 require 'active_support/core_ext/array/extract_options'
18 require 'active_support/core_ext/hash/deep_merge'
19 require 'active_support/core_ext/hash/indifferent_access'
20 require 'active_support/core_ext/hash/slice'
21 require 'active_support/core_ext/string/behavior'
89978f1 @fxn moves Object#singleton_class to Kernel#singleton_class to match Ruby als...
fxn authored
22 require 'active_support/core_ext/kernel/singleton_class'
a7fd564 @lifo Add Model.select/group/order/limit/joins/conditions/preload/eager_load c...
lifo authored
23 require 'active_support/core_ext/module/delegation'
4a8c880 @fxn refactors AR::Base#reset_table_name
fxn authored
24 require 'active_support/core_ext/module/introspection'
105f9b8 @fxn adds missing requires for Object#duplicable?
fxn authored
25 require 'active_support/core_ext/object/duplicable'
76f024a @fxn adds missing requires for Object#blank? and Object#present?
fxn authored
26 require 'active_support/core_ext/object/blank'
0b72a04 @jonleighton Deprecate set_table_name in favour of self.table_name= or defining your ...
jonleighton authored
27 require 'active_support/deprecation'
39d6f9e @wycats Make many parts of Rails lazy. In order to facilitate this,
wycats authored
28 require 'arel'
29 require 'active_record/errors'
6788db8 @josevalim Move Rails::LogSubscriber to ActiveSupport::LogSubscriber, allowing fram...
josevalim authored
30 require 'active_record/log_subscriber'
cfeac38 @fxn implements a much faster auto EXPLAIN, closes #3843 [José Valim & Xavier...
fxn authored
31 require 'active_record/explain_subscriber'
db045db @dhh Initial
dhh authored
32
33 module ActiveRecord #:nodoc:
606088d @eac Mass assignment security refactoring
eac authored
34 # = Active Record
4ad6103 @rizwanreza Adds title and basic description where needed.
rizwanreza authored
35 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
36 # Active Record objects don't specify their attributes directly, but rather infer them from
37 # the table definition with which they're linked. Adding, removing, and changing attributes
38 # and their type is done directly in the database. Any change is instantly reflected in the
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
39 # Active Record objects. The mapping that binds a given Active Record class to a certain
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
40 # database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
41 #
20333be @tilsammans fix broken relative links [#5415 state:committed]
tilsammans authored
42 # See the mapping rules in table_name and the full example in link:files/activerecord/README_rdoc.html for more insight.
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
43 #
db045db @dhh Initial
dhh authored
44 # == Creation
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
45 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
46 # Active Records accept constructor parameters either in a hash or as a block. The hash
47 # method is especially useful when you're receiving the data from somewhere else, like an
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
48 # HTTP request. It works like this:
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
49 #
0591c53 @dhh Made the dynamic finders use the new find API and updated the examples h...
dhh authored
50 # user = User.new(:name => "David", :occupation => "Code Artist")
db045db @dhh Initial
dhh authored
51 # user.name # => "David"
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
52 #
db045db @dhh Initial
dhh authored
53 # You can also use block initialization:
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
54 #
db045db @dhh Initial
dhh authored
55 # user = User.new do |u|
56 # u.name = "David"
57 # u.occupation = "Code Artist"
58 # end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
59 #
db045db @dhh Initial
dhh authored
60 # And of course you can just create a bare object and specify the attributes after the fact:
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
61 #
db045db @dhh Initial
dhh authored
62 # user = User.new
63 # user.name = "David"
64 # user.occupation = "Code Artist"
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
65 #
db045db @dhh Initial
dhh authored
66 # == Conditions
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
67 #
c5ec16e @dhh Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
68 # Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
9e18380 @fxn Revert "Explicitly included hashes in sentence regarding SQL-injection-s...
fxn authored
69 # The array form is to be used when the condition input is tainted and requires sanitization. The string form can
70 # be used for statements that don't involve tainted data. The hash form works much like the array form, except
71 # only equality and range is possible. Examples:
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
72 #
48052d7 @jeremy to_xml fixes, features, and speedup. Closes #4989.
jeremy authored
73 # class User < ActiveRecord::Base
db045db @dhh Initial
dhh authored
74 # def self.authenticate_unsafely(user_name, password)
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
75 # where("user_name = '#{user_name}' AND password = '#{password}'").first
db045db @dhh Initial
dhh authored
76 # end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
77 #
db045db @dhh Initial
dhh authored
78 # def self.authenticate_safely(user_name, password)
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
79 # where("user_name = ? AND password = ?", user_name, password).first
db045db @dhh Initial
dhh authored
80 # end
c5ec16e @dhh Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
81 #
82 # def self.authenticate_safely_simply(user_name, password)
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
83 # where(:user_name => user_name, :password => password).first
c5ec16e @dhh Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
84 # end
db045db @dhh Initial
dhh authored
85 # end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
86 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
87 # The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query
88 # and is thus susceptible to SQL-injection attacks if the <tt>user_name</tt> and +password+
04d37b0 @smartinez87 Remove extra whitespaces
smartinez87 authored
89 # parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
90 # <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+
91 # before inserting them in the query, which will ensure that an attacker can't escape the
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
92 # query and fake the login (or worse).
2575b3b @dhh Added extra words of caution for guarding against SQL-injection attacks
dhh authored
93 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
94 # When using multiple parameters in the conditions, it can easily become hard to read exactly
95 # what the fourth or fifth question mark is supposed to represent. In those cases, you can
96 # resort to named bind variables instead. That's done by replacing the question marks with
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
97 # symbols and supplying a hash with values for the matching symbol keys:
5cd38ca @dhh Added documentation about named bind variables
dhh authored
98 #
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
99 # Company.where(
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
100 # "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
5cd38ca @dhh Added documentation about named bind variables
dhh authored
101 # { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
102 # ).first
5cd38ca @dhh Added documentation about named bind variables
dhh authored
103 #
c5ec16e @dhh Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
104 # Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND
105 # operator. For instance:
106 #
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
107 # Student.where(:first_name => "Harvey", :status => 1)
108 # Student.where(params[:student])
c5ec16e @dhh Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
109 #
2876707 @jeremy Pass a range in :conditions to use the SQL BETWEEN operator. Closes #697...
jeremy authored
110 # A range may be used in the hash to use the SQL BETWEEN operator:
111 #
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
112 # Student.where(:grade => 9..12)
c5ec16e @dhh Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
113 #
aa4af60 @lifo Improve documentation.
lifo authored
114 # An array may be used in the hash to use the SQL IN operator:
115 #
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
116 # Student.where(:grade => [9,11,12])
aa4af60 @lifo Improve documentation.
lifo authored
117 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
118 # When joining tables, nested hashes or keys written in the form 'table_name.column_name'
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
119 # can be used to qualify the table name of a particular condition. For instance:
e033b5d @lifo Merge docrails
lifo authored
120 #
e552fe1 change activerecord query conditions example to avoid 'type' as column n...
Steve Bourne authored
121 # Student.joins(:schools).where(:schools => { :category => 'public' })
122 # Student.joins(:schools).where('schools.category' => 'public' )
e033b5d @lifo Merge docrails
lifo authored
123 #
db045db @dhh Initial
dhh authored
124 # == Overwriting default accessors
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
125 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
126 # All column values are automatically available through basic accessors on the Active Record
127 # object, but sometimes you want to specialize this behavior. This can be done by overwriting
128 # the default accessors (using the same name as the attribute) and calling
129 # <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
130 # change things.
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
131 #
db045db @dhh Initial
dhh authored
132 # class Song < ActiveRecord::Base
133 # # Uses an integer of seconds to hold the length of the song
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
134 #
db045db @dhh Initial
dhh authored
135 # def length=(minutes)
64092de @fxn Improve documentation coverage and markup
fxn authored
136 # write_attribute(:length, minutes.to_i * 60)
db045db @dhh Initial
dhh authored
137 # end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
138 #
db045db @dhh Initial
dhh authored
139 # def length
0591c53 @dhh Made the dynamic finders use the new find API and updated the examples h...
dhh authored
140 # read_attribute(:length) / 60
db045db @dhh Initial
dhh authored
141 # end
142 # end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
143 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
144 # You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt>
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
145 # instead of <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>.
0591c53 @dhh Made the dynamic finders use the new find API and updated the examples h...
dhh authored
146 #
e4d845e Document automatically generated predicate methods for attributes. Close...
Marcel Molina authored
147 # == Attribute query methods
148 #
149 # In addition to the basic accessors, query methods are also automatically available on the Active Record object.
150 # Query methods allow you to test whether an attribute value is present.
7367325 @jeremy Document Active Record exceptions. Closes #10444.
jeremy authored
151 #
e4d845e Document automatically generated predicate methods for attributes. Close...
Marcel Molina authored
152 # For example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call
153 # to determine whether the user has a name:
154 #
155 # user = User.new(:name => "David")
156 # user.name? # => true
157 #
158 # anonymous = User.new(:name => "")
159 # anonymous.name? # => false
160 #
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
161 # == Accessing attributes before they have been typecasted
4eab375 @dhh Finished polishing API docs
dhh authored
162 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
163 # Sometimes you want to be able to read the raw attribute data without having the column-determined
164 # typecast run its course first. That can be done by using the <tt><attribute>_before_type_cast</tt>
165 # accessors that all attributes have. For example, if your Account model has a <tt>balance</tt> attribute,
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
166 # you can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.
4eab375 @dhh Finished polishing API docs
dhh authored
167 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
168 # This is especially useful in validation situations where the user might supply a string for an
169 # integer field and you want to display the original string back in an error message. Accessing the
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
170 # attribute normally would typecast the string to 0, which isn't what you want.
4eab375 @dhh Finished polishing API docs
dhh authored
171 #
ac8fd7d @dhh Added dynamic attribute-based finders as a cleaner way of getting object...
dhh authored
172 # == Dynamic attribute-based finders
173 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
174 # Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects
175 # by simple queries without turning to SQL. They work by appending the name of an attribute
176 # to <tt>find_by_</tt>, <tt>find_last_by_</tt>, or <tt>find_all_by_</tt> and thus produces finders
177 # like <tt>Person.find_by_user_name</tt>, <tt>Person.find_all_by_last_name</tt>, and
178 # <tt>Payment.find_by_transaction_id</tt>. Instead of writing
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
179 # <tt>Person.where(:user_name => user_name).first</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
180 # And instead of writing <tt>Person.where(:last_name => last_name).all</tt>, you just do
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
181 # <tt>Person.find_all_by_last_name(last_name)</tt>.
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
182 #
56efdbc Document exclamation point on dynamic finders
Florent Guilleux authored
183 # It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an
0d5a6f6 @jonleighton In 1efd88283ef68d912df215125951a87526768a51, ConnectionAdapters was put ...
jonleighton authored
184 # <tt>ActiveRecord::RecordNotFound</tt> error if they do not return any records,
56efdbc Document exclamation point on dynamic finders
Florent Guilleux authored
185 # like <tt>Person.find_by_last_name!</tt>.
186 #
d3eacf9 @neerajdotname Adding to AR::Base documentation about dynamically scopeded_by query
neerajdotname authored
187 # It's also possible to use multiple attributes in the same find by separating them with "_and_".
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
188 #
d3eacf9 @neerajdotname Adding to AR::Base documentation about dynamically scopeded_by query
neerajdotname authored
189 # Person.where(:user_name => user_name, :password => password).first
2acb5e3 @fxn removes unrealistic example (authentication plus gender?), that it is no...
fxn authored
190 # Person.find_by_user_name_and_password(user_name, password) # with dynamic finder
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
191 #
d3eacf9 @neerajdotname Adding to AR::Base documentation about dynamically scopeded_by query
neerajdotname authored
192 # It's even possible to call these dynamic finder methods on relations and named scopes.
2c27e3d @lifo Some doc updates reflecting the new query API
lifo authored
193 #
194 # Payment.order("created_on").find_all_by_amount(50)
195 # Payment.pending.find_last_by_amount(100)
959f362 @dhh Added find_all style to the new dynamic finders
dhh authored
196 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
197 # The same dynamic finder style can be used to create the object if it doesn't already exist.
198 # This dynamic finder is called with <tt>find_or_create_by_</tt> and will return the object if
199 # it already exists and otherwise creates it, then returns it. Protected attributes won't be set
200 # unless they are given in a block.
a5a82d9 @dhh Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
201 #
202 # # No 'Summer' tag exists
203 # Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")
7367325 @jeremy Document Active Record exceptions. Closes #10444.
jeremy authored
204 #
a5a82d9 @dhh Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
205 # # Now the 'Summer' tag does exist
206 # Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
207 #
c10b225 @dhh Fixed that ActiveRecord#Base.find_or_create/initialize would not honor a...
dhh authored
208 # # Now 'Bob' exist and is an 'admin'
209 # User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }
210 #
a01f0ab @pixeltrix Add documentation for find_or_create_by_{attribute}! method.
pixeltrix authored
211 # Adding an exclamation point (!) on to the end of <tt>find_or_create_by_</tt> will
212 # raise an <tt>ActiveRecord::RecordInvalid</tt> error if the new record is invalid.
213 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
214 # Use the <tt>find_or_initialize_by_</tt> finder if you want to return a new record without
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
215 # saving it first. Protected attributes won't be set unless they are given in a block.
d19e464 @sstephenson Added find_or_initialize_by_X which works like find_or_create_by_X but d...
sstephenson authored
216 #
217 # # No 'Winter' tag exists
218 # winter = Tag.find_or_initialize_by_name("Winter")
1f06652 @dchelimsky use persisted? instead of new_record? wherever possible
dchelimsky authored
219 # winter.persisted? # false
d19e464 @sstephenson Added find_or_initialize_by_X which works like find_or_create_by_X but d...
sstephenson authored
220 #
14cc8d2 @jeremy find_or_create_by_* takes a hash so you can create with more attributes ...
jeremy authored
221 # To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
222 # a list of parameters.
14cc8d2 @jeremy find_or_create_by_* takes a hash so you can create with more attributes ...
jeremy authored
223 #
224 # Tag.find_or_create_by_name(:name => "rails", :creator => current_user)
225 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
226 # That will either find an existing tag named "rails", or create a new one while setting the
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
227 # user that created it.
14cc8d2 @jeremy find_or_create_by_* takes a hash so you can create with more attributes ...
jeremy authored
228 #
d3eacf9 @neerajdotname Adding to AR::Base documentation about dynamically scopeded_by query
neerajdotname authored
229 # Just like <tt>find_by_*</tt>, you can also use <tt>scoped_by_*</tt> to retrieve data. The good thing about
230 # using this feature is that the very first time result is returned using <tt>method_missing</tt> technique
231 # but after that the method is declared on the class. Henceforth <tt>method_missing</tt> will not be hit.
232 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
233 # User.scoped_by_user_name('David')
d3eacf9 @neerajdotname Adding to AR::Base documentation about dynamically scopeded_by query
neerajdotname authored
234 #
098fa94 @dhh Fixed documentation snafus #575, #576, #577, #585
dhh authored
235 # == Saving arrays, hashes, and other non-mappable objects in text columns
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
236 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
237 # Active Record can serialize any object in text columns using YAML. To do so, you must
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
238 # specify this with a call to the class method +serialize+.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
239 # This makes it possible to store arrays, hashes, and other non-mappable objects without doing
240 # any additional work.
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
241 #
db045db @dhh Initial
dhh authored
242 # class User < ActiveRecord::Base
243 # serialize :preferences
244 # end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
245 #
ca2eb16 Fix syntax error in documentation. Closes #4679. [mislav@nippur.irb.hr]
Marcel Molina authored
246 # user = User.create(:preferences => { "background" => "black", "display" => large })
db045db @dhh Initial
dhh authored
247 # User.find(user.id).preferences # => { "background" => "black", "display" => large }
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
248 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
249 # You can also specify a class option as the second parameter that'll raise an exception
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
250 # if a serialized object is retrieved as a descendant of a class not in the hierarchy.
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
251 #
db045db @dhh Initial
dhh authored
252 # class User < ActiveRecord::Base
66f44e6 @dhh Updated documentation for serialize
dhh authored
253 # serialize :preferences, Hash
db045db @dhh Initial
dhh authored
254 # end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
255 #
0591c53 @dhh Made the dynamic finders use the new find API and updated the examples h...
dhh authored
256 # user = User.create(:preferences => %w( one two three ))
db045db @dhh Initial
dhh authored
257 # User.find(user.id).preferences # raises SerializationTypeMismatch
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
258 #
351331f @guillermo Make serialized columns with explicit object_type return a new instance ...
guillermo authored
259 # When you specify a class option, the default value for that attribute will be a new
260 # instance of that class.
261 #
262 # class User < ActiveRecord::Base
263 # serialize :preferences, OpenStruct
264 # end
265 #
266 # user = User.new
267 # user.preferences.theme_color = "red"
268 #
269 #
db045db @dhh Initial
dhh authored
270 # == Single table inheritance
271 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
272 # Active Record allows inheritance by storing the name of the class in a column that by
273 # default is named "type" (can be changed by overwriting <tt>Base.inheritance_column</tt>).
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
274 # This means that an inheritance looking like this:
db045db @dhh Initial
dhh authored
275 #
276 # class Company < ActiveRecord::Base; end
277 # class Firm < Company; end
278 # class Client < Company; end
279 # class PriorityClient < Client; end
280 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
281 # When you do <tt>Firm.create(:name => "37signals")</tt>, this record will be saved in
282 # the companies table with type = "Firm". You can then fetch this row again using
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
283 # <tt>Company.where(:name => '37signals').first</tt> and it will return a Firm object.
db045db @dhh Initial
dhh authored
284 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
285 # If you don't have a type column defined in your table, single-table inheritance won't
286 # be triggered. In that case, it'll work just like normal subclasses with no special magic
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
287 # for differentiating between them or reloading the right type with find.
f033833 @dhh Improving documentation...
dhh authored
288 #
db045db @dhh Initial
dhh authored
289 # Note, all the attributes for all the cases are kept in the same table. Read more:
290 # http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
291 #
db045db @dhh Initial
dhh authored
292 # == Connection to multiple databases in different models
293 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
294 # Connections are usually created through ActiveRecord::Base.establish_connection and retrieved
295 # by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this
296 # connection. But you can also set a class-specific connection. For example, if Course is an
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
297 # ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
98dc582 @lifo Merge docrails.
lifo authored
298 # and Course and all of its subclasses will use this connection instead.
db045db @dhh Initial
dhh authored
299 #
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
300 # This feature is implemented by keeping a connection pool in ActiveRecord::Base that is
301 # a Hash indexed by the class. If a connection is requested, the retrieve_connection method
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
302 # will go up the class-hierarchy until a connection is found in the connection pool.
db045db @dhh Initial
dhh authored
303 #
304 # == Exceptions
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
305 #
dc4eec1 @lifo Merge docrails:
lifo authored
306 # * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
307 # * AdapterNotSpecified - The configuration hash used in <tt>establish_connection</tt> didn't include an
db045db @dhh Initial
dhh authored
308 # <tt>:adapter</tt> key.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
309 # * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
310 # non-existent adapter
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
311 # (or a bad spelling of an existing one).
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
312 # * AssociationTypeMismatch - The object assigned to the association wasn't of the type
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
313 # specified in the association definition.
dc4eec1 @lifo Merge docrails:
lifo authored
314 # * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
315 # * ConnectionNotEstablished+ - No connection has been established. Use <tt>establish_connection</tt>
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
316 # before querying.
dc4eec1 @lifo Merge docrails:
lifo authored
317 # * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist
318 # or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal
319 # nothing was found, please check its documentation for further details.
320 # * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
321 # * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
322 # <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
323 # AttributeAssignmentError
d2fefbe @dhh Added MultiparameterAssignmentErrors and AttributeAssignmentError except...
dhh authored
324 # objects that should be inspected to determine which attributes triggered the errors.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
325 # * AttributeAssignmentError - An error occurred while doing a mass assignment through the
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
326 # <tt>attributes=</tt> method.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
327 # You can inspect the +attribute+ property of the exception object to determine which attribute
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
328 # triggered the error.
5707027 @dhh Added better exception error when unknown column types are used with mig...
dhh authored
329 #
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
330 # *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
dc4eec1 @lifo Merge docrails:
lifo authored
331 # So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
db045db @dhh Initial
dhh authored
332 # instances in the current object space.
333 class Base
0905396 @miloops construct_finder_sql now use Arel
miloops authored
334 ##
dbbae5e @lifo Merge with docrails
lifo authored
335 # :singleton-method:
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
336 # Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class,
337 # which is then passed on to any new database connections made and which can be retrieved on both
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
338 # a class and instance level by calling +logger+.
1a11bff @technoweenie Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
339 cattr_accessor :logger, :instance_writer => false
e694114 @jeremy Deprecation: removed Reloadable.
jeremy authored
340
dbbae5e @lifo Merge with docrails
lifo authored
341 ##
342 # :singleton-method:
a293278 @lifo Merge docrails
lifo authored
343 # Contains the database configuration - as is typically stored in config/database.yml -
344 # as a Hash.
345 #
346 # For example, the following database.yml...
0905396 @miloops construct_finder_sql now use Arel
miloops authored
347 #
a293278 @lifo Merge docrails
lifo authored
348 # development:
349 # adapter: sqlite3
350 # database: db/development.sqlite3
0905396 @miloops construct_finder_sql now use Arel
miloops authored
351 #
a293278 @lifo Merge docrails
lifo authored
352 # production:
353 # adapter: sqlite3
354 # database: db/production.sqlite3
355 #
356 # ...would result in ActiveRecord::Base.configurations to look like this:
357 #
358 # {
359 # 'development' => {
360 # 'adapter' => 'sqlite3',
361 # 'database' => 'db/development.sqlite3'
362 # },
363 # 'production' => {
364 # 'adapter' => 'sqlite3',
365 # 'database' => 'db/production.sqlite3'
366 # }
367 # }
1a11bff @technoweenie Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
368 cattr_accessor :configurations, :instance_writer => false
c4a3634 @jeremy Corrected @@configurations typo. #1410 [david@ruppconsulting.com]
jeremy authored
369 @@configurations = {}
370
dbbae5e @lifo Merge with docrails
lifo authored
371 ##
372 # :singleton-method:
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
373 # Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling
b8d9d9c @neerajdotname updating documentation to ensure line does not exceed 100 columns
neerajdotname authored
374 # dates and times from the database. This is set to :local by default.
1a11bff @technoweenie Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
375 cattr_accessor :default_timezone, :instance_writer => false
60de8c1 @dhh Added Base.default_timezone accessor that determines whether to use Time...
dhh authored
376 @@default_timezone = :local
d8641ca @jeremy CHANGED DEFAULT: set ActiveRecord::Base.allow_concurrency to false. Mos...
jeremy authored
377
dbbae5e @lifo Merge with docrails
lifo authored
378 ##
379 # :singleton-method:
24c3599 @sstephenson Support using different database adapters for development and test with ...
sstephenson authored
380 # Specifies the format to use when dumping the database schema with Rails'
04d37b0 @smartinez87 Remove extra whitespaces
smartinez87 authored
381 # Rakefile. If :sql, the schema is dumped as (potentially database-
382 # specific) SQL statements. If :ruby, the schema is dumped as an
24c3599 @sstephenson Support using different database adapters for development and test with ...
sstephenson authored
383 # ActiveRecord::Schema file which can be loaded into any database that
04d37b0 @smartinez87 Remove extra whitespaces
smartinez87 authored
384 # supports migrations. Use :ruby if you want to have different database
24c3599 @sstephenson Support using different database adapters for development and test with ...
sstephenson authored
385 # adapters for, e.g., your development and test environments.
1a11bff @technoweenie Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
386 cattr_accessor :schema_format , :instance_writer => false
660952e @dhh CHANGED DEFAULT: ActiveRecord::Base.schema_format is now :ruby by defaul...
dhh authored
387 @@schema_format = :ruby
3b0e1d9 @josh Prefer string core_ext inflector methods over directly accessing Inflect...
josh authored
388
dbbae5e @lifo Merge with docrails
lifo authored
389 ##
390 # :singleton-method:
155f0be @rizwanreza Changes migration number to version due to ambiguity. [#3065 state:commi...
rizwanreza authored
391 # Specify whether or not to use timestamps for migration versions
bbab639 @nikz Set config.active_record.timestamped_migrations = false to have migratio...
nikz authored
392 cattr_accessor :timestamped_migrations , :instance_writer => false
393 @@timestamped_migrations = true
394
db045db @dhh Initial
dhh authored
395 class << self # Class methods
61bcc31 @joshsusser use GeneratedFeatureMethods module for associations
joshsusser authored
396 def inherited(child_class) #:nodoc:
fab664a @jonleighton Fix another race condition.
jonleighton authored
397 child_class.initialize_generated_modules
61bcc31 @joshsusser use GeneratedFeatureMethods module for associations
joshsusser authored
398 super
399 end
400
fab664a @jonleighton Fix another race condition.
jonleighton authored
401 def initialize_generated_modules #:nodoc:
402 @attribute_methods_mutex = Mutex.new
403
404 # force attribute methods to be higher in inheritance hierarchy than other generated methods
405 generated_attribute_methods
406 generated_feature_methods
407 end
408
61bcc31 @joshsusser use GeneratedFeatureMethods module for associations
joshsusser authored
409 def generated_feature_methods
3da5fba @jonleighton Fix ruby 1.8 compat. const_defined? only takes a second arg on 1.9.
jonleighton authored
410 @generated_feature_methods ||= begin
411 mod = const_set(:GeneratedFeatureMethods, Module.new)
412 include mod
413 mod
61bcc31 @joshsusser use GeneratedFeatureMethods module for associations
joshsusser authored
414 end
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
415 end
fd40fbc @jeremy Generate less garbage when expanding range bind variables in conditions
jeremy authored
416
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
417 # Returns a string like 'Post(id:integer, title:string, body:text)'
418 def inspect
419 if self == Base
420 super
421 elsif abstract_class?
422 "#{super}(abstract)"
423 elsif table_exists?
424 attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
425 "#{super}(#{attr_list})"
426 else
427 "#{super}(Table doesn't exist)"
428 end
429 end
cd994ef @lifo Allow conditions on multiple tables to be specified using hash.
lifo authored
430
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
431 # Overwrite the default class equality method to provide support for association proxies.
432 def ===(object)
433 object.is_a?(self)
434 end
fd40fbc @jeremy Generate less garbage when expanding range bind variables in conditions
jeremy authored
435
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
436 def arel_table
437 @arel_table ||= Arel::Table.new(table_name, arel_engine)
438 end
2876707 @jeremy Pass a range in :conditions to use the SQL BETWEEN operator. Closes #697...
jeremy authored
439
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
440 def arel_engine
441 @arel_engine ||= begin
442 if self == ActiveRecord::Base
443 ActiveRecord::Base
c2ed453 @dhh Fix quote_bound_value to not map Strings #1416 [htonl]
dhh authored
444 else
21d9c0f @kennyj [3-2-stable] Fix GH #5399. connection_pools's keys are ActiveRecord::Bas...
kennyj authored
445 connection_handler.retrieve_connection_pool(self) ? self : superclass.arel_engine
872ddaf @dhh Added bind-named arrays for interpolating a group of ids or strings in c...
dhh authored
446 end
447 end
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
448 end
872ddaf @dhh Added bind-named arrays for interpolating a group of ids or strings in c...
dhh authored
449
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
450 private
554597d @dhh Added named bind-style variable interpolation #281 [Michael Koziarski]
dhh authored
451
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
452 def relation #:nodoc:
8dbf337 backport 68677ffb8298105eb9d3efa26d928dd88cc5e006
Evan Petrie authored
453 relation = Relation.new(self, arel_table)
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
454
455 if finder_needs_type_condition?
8dbf337 backport 68677ffb8298105eb9d3efa26d928dd88cc5e006
Evan Petrie authored
456 relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
457 else
8dbf337 backport 68677ffb8298105eb9d3efa26d928dd88cc5e006
Evan Petrie authored
458 relation
aaf9a45 @dhh Added Base.validate_uniqueness thatv alidates whether the value of the s...
dhh authored
459 end
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
460 end
db045db @dhh Initial
dhh authored
461 end
462
463 public
464 # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
465 # attributes but not yet saved (pass a hash with key names matching the associated table column names).
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
466 # In both instances, valid attribute keys are determined by the column names of the associated table --
db045db @dhh Initial
dhh authored
467 # hence you can't have attributes that aren't part of the table columns.
7c5ae0a @joshk Added mass-assignment security :as and :without_protection support to AR...
joshk authored
468 #
469 # +initialize+ respects mass-assignment security and accepts either +:as+ or +:without_protection+ options
470 # in the +options+ parameter.
471 #
472 # ==== Examples
473 # # Instantiates a single new object
474 # User.new(:first_name => 'Jamie')
475 #
b2451f4 @joshk renamed mass-assignment scopes to roles, updated code, tests, docs and s...
joshk authored
476 # # Instantiates a single new object using the :admin mass-assignment security role
7c5ae0a @joshk Added mass-assignment security :as and :without_protection support to AR...
joshk authored
477 # User.new({ :first_name => 'Jamie', :is_admin => true }, :as => :admin)
478 #
479 # # Instantiates a single new object bypassing mass-assignment security
480 # User.new({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true)
481 def initialize(attributes = nil, options = {})
6a0a5f3 @drogus Duplicate column_defaults properly
drogus authored
482 defaults = Hash[self.class.column_defaults.map { |k, v| [k, v.duplicable? ? v.dup : v] }]
483 @attributes = self.class.initialize_attributes(defaults)
839f3bf @tenderlove just use a hash for doing association caching
tenderlove authored
484 @association_cache = {}
344a2d5 @tenderlove use a hash for caching aggregations rather than ivars
tenderlove authored
485 @aggregation_cache = {}
5b801b5 @NZKoz Change the implementation of ActiveRecord's attribute reader and writer ...
NZKoz authored
486 @attributes_cache = {}
e444439 @josevalim Partialy revert f1c13b0dd7b22b5f6289ca1a09f1d7a8c7c8584b
josevalim authored
487 @new_record = true
95bd56e @tenderlove speeding up clone_attributes, changing readonly to be initialized in def...
tenderlove authored
488 @readonly = false
5de3698 @tenderlove cleaning up many more warnings in activerecord [#4180 state:resolved]
tenderlove authored
489 @destroyed = false
490 @marked_for_destruction = false
8c3e46c @tenderlove clean up more warnings, remove unnecessary methods, fix eval line number...
tenderlove authored
491 @previously_changed = {}
492 @changed_attributes = {}
5de3698 @tenderlove cleaning up many more warnings in activerecord [#4180 state:resolved]
tenderlove authored
493
db045db @dhh Initial
dhh authored
494 ensure_proper_type
3da29f6 @lifo Remove AR#scope() method
lifo authored
495
cdfd013 @marklazz Set attributes properly for model built from association with conditions...
marklazz authored
496 populate_with_current_scope_attributes
7c5ae0a @joshk Added mass-assignment security :as and :without_protection support to AR...
joshk authored
497
498 assign_attributes(attributes, options) if attributes
3da29f6 @lifo Remove AR#scope() method
lifo authored
499
26caf32 @tenderlove remove useless assignment
tenderlove authored
500 yield self if block_given?
57bc25c @jfirebaugh Use run_callbacks; the generated _run_<name>_callbacks method is not a p...
jfirebaugh authored
501 run_callbacks :initialize
db045db @dhh Initial
dhh authored
502 end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
503
04d37b0 @smartinez87 Remove extra whitespaces
smartinez87 authored
504 # Initialize an empty model object from +coder+. +coder+ must contain
505 # the attributes necessary for initializing an empty model object. For
505b532 @tenderlove speeding up object instantiation by eliminating instance_eval
tenderlove authored
506 # example:
507 #
508 # class Post < ActiveRecord::Base
509 # end
510 #
511 # post = Post.allocate
512 # post.init_with('attributes' => { 'title' => 'hello world' })
513 # post.title # => 'hello world'
514 def init_with(coder)
7edade3 @jonleighton Make read_attribute code path accessible at the class level
jonleighton authored
515 @attributes = self.class.initialize_attributes(coder['attributes'])
5ddb60f @tenderlove initialize instance variables
tenderlove authored
516 @relation = nil
5b42e96 @tenderlove make sure de-serialization happens on object instantiation
tenderlove authored
517
505b532 @tenderlove speeding up object instantiation by eliminating instance_eval
tenderlove authored
518 @attributes_cache, @previously_changed, @changed_attributes = {}, {}, {}
839f3bf @tenderlove just use a hash for doing association caching
tenderlove authored
519 @association_cache = {}
344a2d5 @tenderlove use a hash for caching aggregations rather than ivars
tenderlove authored
520 @aggregation_cache = {}
1f06652 @dchelimsky use persisted? instead of new_record? wherever possible
dchelimsky authored
521 @readonly = @destroyed = @marked_for_destruction = false
e444439 @josevalim Partialy revert f1c13b0dd7b22b5f6289ca1a09f1d7a8c7c8584b
josevalim authored
522 @new_record = false
57bc25c @jfirebaugh Use run_callbacks; the generated _run_<name>_callbacks method is not a p...
jfirebaugh authored
523 run_callbacks :find
524 run_callbacks :initialize
24485b9 @swistak Separated initialization
swistak authored
525
526 self
505b532 @tenderlove speeding up object instantiation by eliminating instance_eval
tenderlove authored
527 end
528
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
529 # Duped objects have no id assigned and are treated as new records. Note
530 # that this is a "shallow" copy as it copies the object's attributes
531 # only, not its associations. The extent of a "deep" copy is application
532 # specific and is therefore left to the application to implement according
533 # to its need.
534 # The dup method does not preserve the timestamps (created|updated)_(at|on).
535 def initialize_dup(other)
536 cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
c470001 @tenderlove Merge pull request #5810 from kennyj/fix_5797
tenderlove authored
537 self.class.initialize_attributes(cloned_attributes, :serialized => false)
77b4edc @jonleighton Fix attribute_before_type_cast for serialized attributes. Fixes #4837.
jonleighton authored
538
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
539 cloned_attributes.delete(self.class.primary_key)
9e4b715 @josevalim Ensure assign_attributes and update_attributes do not fail on nil, close...
josevalim authored
540
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
541 @attributes = cloned_attributes
a08d04b @joshk Added assign_attributes to Active Record which accepts a mass-assignment...
joshk authored
542
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
543 _run_after_initialize_callbacks if respond_to?(:_run_after_initialize_callbacks)
7367325 @jeremy Document Active Record exceptions. Closes #10444.
jeremy authored
544
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
545 @changed_attributes = {}
7edade3 @jonleighton Make read_attribute code path accessible at the class level
jonleighton authored
546 self.class.column_defaults.each do |attr, orig_value|
b8fba55 @tenderlove Merge pull request #3544 from amatsuda/_field_changed
tenderlove authored
547 @changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @attributes[attr])
db045db @dhh Initial
dhh authored
548 end
3d0a9ff @dhh Aesthetics, baby
dhh authored
549
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
550 @aggregation_cache = {}
551 @association_cache = {}
552 @attributes_cache = {}
553 @new_record = true
774ff18 @akaspick Allow nested attributes in associations to update values in it's owner o...
akaspick authored
554
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
555 ensure_proper_type
556 super
db045db @dhh Initial
dhh authored
557 end
558
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
559 # Backport dup from 1.9 so that initialize_dup() gets called
127411f @hsbt handled respond_to? with private methods
hsbt authored
560 unless Object.respond_to?(:initialize_dup, true)
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
561 def dup # :nodoc:
562 copy = super
563 copy.initialize_dup(self)
564 copy
565 end
bd79a4e @dhh Fixed that clone would break when an aggregate had the same name as one ...
dhh authored
566 end
567
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
568 # Populate +coder+ with attributes about this record that should be
569 # serialized. The structure of +coder+ defined in this method is
570 # guaranteed to match the structure of +coder+ passed to the +init_with+
571 # method.
39e1ac6 @lifo Merge docrails
lifo authored
572 #
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
573 # Example:
39e1ac6 @lifo Merge docrails
lifo authored
574 #
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
575 # class Post < ActiveRecord::Base
576 # end
577 # coder = {}
578 # Post.new.encode_with(coder)
579 # coder # => { 'id' => nil, ... }
580 def encode_with(coder)
581 coder['attributes'] = attributes
db045db @dhh Initial
dhh authored
582 end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
583
d7db6a8 @joshk class inheritable attributes is used no more! all internal use of class ...
joshk authored
584 # Returns true if +comparison_object+ is the same exact object, or +comparison_object+
a820d0a @fxn revises RDoc of AR::Base#==
fxn authored
585 # is of the same type and +self+ has an ID and it is equal to +comparison_object.id+.
586 #
587 # Note that new records are different from any other record by definition, unless the
588 # other record is the receiver itself. Besides, if you fetch existing records with
589 # +select+ and leave the ID out, you're on your own, this predicate will return false.
590 #
591 # Note also that destroying a record preserves its ID in the model instance, so deleted
592 # models are still comparable.
db045db @dhh Initial
dhh authored
593 def ==(comparison_object)
8e19a5d @tenderlove call super rather than delegating to the other objects equal? method
tenderlove authored
594 super ||
4718d09 @spastorino Models should be equals even after destroyed
spastorino authored
595 comparison_object.instance_of?(self.class) &&
596 id.present? &&
597 comparison_object.id == id
db045db @dhh Initial
dhh authored
598 end
2545da6 @tenderlove just alias eql? to == for frewer method calls
tenderlove authored
599 alias :eql? :==
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
600
db045db @dhh Initial
dhh authored
601 # Delegates to id in order to allow two records of the same type and id to work with something like:
602 # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
603 def hash
cfef86c @dhh Fixed bug in Base#hash method that would treat records with the same str...
dhh authored
604 id.hash
db045db @dhh Initial
dhh authored
605 end
606
8c2177c Add documentation for freeze and readonly related methods. Closes #8878 ...
Marcel Molina authored
607 # Freeze the attributes hash such that associations are still accessible, even on destroyed records.
24a9050 @dhh Changed the callbacks such that observers are notified before the in-obj...
dhh authored
608 def freeze
b1a4f91 @jamis Make destroy return self #1913 [sebastian.kanthak@muehlheim.de]
jamis authored
609 @attributes.freeze; self
24a9050 @dhh Changed the callbacks such that observers are notified before the in-obj...
dhh authored
610 end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
611
8c2177c Add documentation for freeze and readonly related methods. Closes #8878 ...
Marcel Molina authored
612 # Returns +true+ if the attributes hash has been frozen.
24a9050 @dhh Changed the callbacks such that observers are notified before the in-obj...
dhh authored
613 def frozen?
614 @attributes.frozen?
615 end
6e39c9e @jeremy r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
616
bc743dc @dmathieu allow comparison on model objects - Closes #1858
dmathieu authored
617 # Allows sort on objects
618 def <=>(other_object)
eb22c51 @dmathieu comparing different classes returns nil
dmathieu authored
619 if other_object.is_a?(self.class)
620 self.to_key <=> other_object.to_key
621 else
622 nil
623 end
bc743dc @dmathieu allow comparison on model objects - Closes #1858
dmathieu authored
624 end
625
8c2177c Add documentation for freeze and readonly related methods. Closes #8878 ...
Marcel Molina authored
626 # Returns +true+ if the record is read only. Records loaded through joins with piggy-back
627 # attributes will be marked as read only since they cannot be saved.
64fcb75 @jeremy r3618@sedna: jeremy | 2005-10-14 12:06:03 -0700
jeremy authored
628 def readonly?
95bd56e @tenderlove speeding up clone_attributes, changing readonly to be initialized in def...
tenderlove authored
629 @readonly
64fcb75 @jeremy r3618@sedna: jeremy | 2005-10-14 12:06:03 -0700
jeremy authored
630 end
631
8c2177c Add documentation for freeze and readonly related methods. Closes #8878 ...
Marcel Molina authored
632 # Marks this record as read only.
633 def readonly!
64fcb75 @jeremy r3618@sedna: jeremy | 2005-10-14 12:06:03 -0700
jeremy authored
634 @readonly = true
635 end
d872281 @dhh Fixed to_xml across the board to use nice indention, better skip_attribu...
dhh authored
636
8c2177c Add documentation for freeze and readonly related methods. Closes #8878 ...
Marcel Molina authored
637 # Returns the contents of the record as a nicely formatted string.
e48b062 @jeremy Sanitize Base#inspect. Closes #8392.
jeremy authored
638 def inspect
b2db874 @franckverrot Fix the AR::Base#inspect method [closes #1294]
franckverrot authored
639 inspection = if @attributes
640 self.class.column_names.collect { |name|
641 if has_attribute?(name)
642 "#{name}: #{attribute_for_inspect(name)}"
643 end
644 }.compact.join(", ")
645 else
646 "not initialized"
647 end
648 "#<#{self.class} #{inspection}>"
e48b062 @jeremy Sanitize Base#inspect. Closes #8392.
jeremy authored
649 end
64fcb75 @jeremy r3618@sedna: jeremy | 2005-10-14 12:06:03 -0700
jeremy authored
650
52eedf5 @jonleighton Add hackery to make Syck use encode_with/init_with. Fixes 1.8 after rece...
jonleighton authored
651 # Hackery to accomodate Syck. Remove for 4.0.
652 def to_yaml(opts = {}) #:nodoc:
653 if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck?
654 super
655 else
656 coder = {}
657 encode_with(coder)
658 YAML.quick_emit(self, opts) do |out|
659 out.map(taguri, to_yaml_style) do |map|
660 coder.each { |k, v| map.add(k, v) }
661 end
662 end
663 end
664 end
665
666 # Hackery to accomodate Syck. Remove for 4.0.
667 def yaml_initialize(tag, coder) #:nodoc:
668 init_with(coder)
669 end
670
db045db @dhh Initial
dhh authored
671 private
672
e9fa602 @jonleighton Define to_ary on ActiveRecord::Base to return nil. Improve performance o...
jonleighton authored
673 # Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements
674 # of the array, and then rescues from the possible NoMethodError. If those elements are
675 # ActiveRecord::Base's, then this triggers the various method_missing's that we have,
676 # which significantly impacts upon performance.
677 #
678 # So we can avoid the method_missing hit by explicitly defining #to_ary as nil here.
679 #
680 # See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/
681 def to_ary # :nodoc:
682 nil
683 end
684
d916c62 @wycats eliminate alias_method_chain from ActiveRecord
wycats authored
685 include ActiveRecord::Persistence
1c4d28b @josh Move model naming into ActiveModel
josh authored
686 extend ActiveModel::Naming
aa002c0 @josh ActiveRecord::QueryCache middleware
josh authored
687 extend QueryCache::ClassMethods
a15e02d @josevalim Unify benchmark APIs.
josevalim authored
688 extend ActiveSupport::Benchmarkable
033e0a0 @josevalim ActiveRecord and ActionPack now use the new descendants implementation.
josevalim authored
689 extend ActiveSupport::DescendantsTracker
a15e02d @josevalim Unify benchmark APIs.
josevalim authored
690
ceb33f8 @jonleighton Split out most of the AR::Base code into separate modules :cake:
jonleighton authored
691 extend Querying
692 include ReadonlyAttributes
693 include ModelSchema
694 extend Translation
695 include Inheritance
696 include Scoping
697 extend DynamicMatchers
698 include Sanitization
699 include AttributeAssignment
56bed51 @josevalim Fix dom_id for ActiveRecord [#4296 state:resolved]
josevalim authored
700 include ActiveModel::Conversion
9b5309f @jfirebaugh AR::Integration must be included after AM::Conversion
jfirebaugh authored
701 include Integration
7254d23 @josh Autoload ActiveRecord files
josh authored
702 include Validations
d916c62 @wycats eliminate alias_method_chain from ActiveRecord
wycats authored
703 extend CounterCache
7254d23 @josh Autoload ActiveRecord files
josh authored
704 include Locking::Optimistic, Locking::Pessimistic
705 include AttributeMethods
4d70359 @josh Integrate ActiveModel::Observing into ActiveRecord
josh authored
706 include Callbacks, ActiveModel::Observing, Timestamp
2b22564 @jonleighton Move DefaultScope and NamedScope under Scoping
jonleighton authored
707 include Associations
ce66bfd @swistak IdentityMap - misc fixes
swistak authored
708 include IdentityMap
bcf4e4f @dhh Added ActiveRecord::Base#has_secure_password (via ActiveModel::SecurePas...
dhh authored
709 include ActiveModel::SecurePassword
0065f37 @fxn AS::Concern is not really needed for AR::Explain
fxn authored
710 extend Explain
ec8f045 @alloy Add support for nested object forms to ActiveRecord and the helpers in A...
alloy authored
711
712 # AutosaveAssociation needs to be included before Transactions, because we want
713 # #save_with_autosave_associations to be wrapped inside a transaction.
714 include AutosaveAssociation, NestedAttributes
85b64f9 @dhh Added ActiveRecord::Base.store for declaring simple single-column key/va...
dhh authored
715 include Aggregations, Transactions, Reflection, Serialization, Store
7254d23 @josh Autoload ActiveRecord files
josh authored
716 end
15aa6e0 @jeremy r4644@asus: jeremy | 2006-06-16 14:57:03 -0700
jeremy authored
717 end
d6b923a @josh get activerecord tests passing with lazy loading
josh authored
718
0d5a6f6 @jonleighton In 1efd88283ef68d912df215125951a87526768a51, ConnectionAdapters was put ...
jonleighton authored
719 require 'active_record/connection_adapters/abstract/connection_specification'
4aded43 @wycats Replace the placeholder base_hook API with on_load. To specify some code...
wycats authored
720 ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
Something went wrong with that request. Please try again.