Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 1928 lines (1739 sloc) 86.582 kb
db045db David Heinemeier Hansson Initial
dhh authored
1 require 'yaml'
aabf909 Jeremy Kemper Correct reader method generation for primary key attribute: handle case ...
jeremy authored
2 require 'set'
a15e02d José Valim Unify benchmark APIs.
josevalim authored
3 require 'active_support/benchmarkable'
f5d720f Jeremy Kemper Opt in to Dependencies
jeremy authored
4 require 'active_support/dependencies'
5f222c5 Jeremy Kemper Remove 'core' fluff. Hookable ActiveSupport.load_all!
jeremy authored
5 require 'active_support/time'
bab1f91 Phil Smith table_name_prefix and table_name_suffix are class_attributes instead of ...
phs authored
6 require 'active_support/core_ext/class/attribute'
e8550ee Jeremy Kemper Cherry-pick core extensions
jeremy authored
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'
89978f1 Xavier Noria moves Object#singleton_class to Kernel#singleton_class to match Ruby als...
fxn authored
15 require 'active_support/core_ext/kernel/singleton_class'
a7fd564 Pratik Add Model.select/group/order/limit/joins/conditions/preload/eager_load c...
lifo authored
16 require 'active_support/core_ext/module/delegation'
4a8c880 Xavier Noria refactors AR::Base#reset_table_name
fxn authored
17 require 'active_support/core_ext/module/introspection'
105f9b8 Xavier Noria adds missing requires for Object#duplicable?
fxn authored
18 require 'active_support/core_ext/object/duplicable'
76f024a Xavier Noria adds missing requires for Object#blank? and Object#present?
fxn authored
19 require 'active_support/core_ext/object/blank'
39d6f9e Yehuda Katz Make many parts of Rails lazy. In order to facilitate this,
wycats authored
20 require 'arel'
21 require 'active_record/errors'
db045db David Heinemeier Hansson Initial
dhh authored
22
23 module ActiveRecord #:nodoc:
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
24 # Active Record objects don't specify their attributes directly, but rather infer them from the table definition with
db045db David Heinemeier Hansson Initial
dhh authored
25 # which they're linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change
26 # is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
27 # database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
28 #
db045db David Heinemeier Hansson Initial
dhh authored
29 # See the mapping rules in table_name and the full example in link:files/README.html for more insight.
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
30 #
db045db David Heinemeier Hansson Initial
dhh authored
31 # == Creation
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
32 #
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
33 # Active Records accept constructor parameters either in a hash or as a block. The hash method is especially useful when
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
34 # you're receiving the data from somewhere else, like an HTTP request. It works like this:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
35 #
0591c53 David Heinemeier Hansson Made the dynamic finders use the new find API and updated the examples h...
dhh authored
36 # user = User.new(:name => "David", :occupation => "Code Artist")
db045db David Heinemeier Hansson Initial
dhh authored
37 # user.name # => "David"
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
38 #
db045db David Heinemeier Hansson Initial
dhh authored
39 # You can also use block initialization:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
40 #
db045db David Heinemeier Hansson Initial
dhh authored
41 # user = User.new do |u|
42 # u.name = "David"
43 # u.occupation = "Code Artist"
44 # end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
45 #
db045db David Heinemeier Hansson Initial
dhh authored
46 # And of course you can just create a bare object and specify the attributes after the fact:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
47 #
db045db David Heinemeier Hansson Initial
dhh authored
48 # user = User.new
49 # user.name = "David"
50 # user.occupation = "Code Artist"
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
51 #
db045db David Heinemeier Hansson Initial
dhh authored
52 # == Conditions
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
53 #
c5ec16e David Heinemeier Hansson Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
54 # Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
db045db David Heinemeier Hansson Initial
dhh authored
55 # The array form is to be used when the condition input is tainted and requires sanitization. The string form can
c5ec16e David Heinemeier Hansson Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
56 # be used for statements that don't involve tainted data. The hash form works much like the array form, except
2876707 Jeremy Kemper Pass a range in :conditions to use the SQL BETWEEN operator. Closes #697...
jeremy authored
57 # only equality and range is possible. Examples:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
58 #
48052d7 Jeremy Kemper to_xml fixes, features, and speedup. Closes #4989.
jeremy authored
59 # class User < ActiveRecord::Base
db045db David Heinemeier Hansson Initial
dhh authored
60 # def self.authenticate_unsafely(user_name, password)
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
61 # where("user_name = '#{user_name}' AND password = '#{password}'").first
db045db David Heinemeier Hansson Initial
dhh authored
62 # end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
63 #
db045db David Heinemeier Hansson Initial
dhh authored
64 # def self.authenticate_safely(user_name, password)
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
65 # where("user_name = ? AND password = ?", user_name, password).first
db045db David Heinemeier Hansson Initial
dhh authored
66 # end
c5ec16e David Heinemeier Hansson Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
67 #
68 # def self.authenticate_safely_simply(user_name, password)
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
69 # where(:user_name => user_name, :password => password).first
c5ec16e David Heinemeier Hansson Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
70 # end
db045db David Heinemeier Hansson Initial
dhh authored
71 # end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
72 #
2575b3b David Heinemeier Hansson Added extra words of caution for guarding against SQL-injection attacks
dhh authored
73 # The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query and is thus susceptible to SQL-injection
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
74 # attacks if the <tt>user_name</tt> and +password+ parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
75 # <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+ before inserting them in the query,
c5ec16e David Heinemeier Hansson Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
76 # which will ensure that an attacker can't escape the query and fake the login (or worse).
2575b3b David Heinemeier Hansson Added extra words of caution for guarding against SQL-injection attacks
dhh authored
77 #
5cd38ca David Heinemeier Hansson Added documentation about named bind variables
dhh authored
78 # When using multiple parameters in the conditions, it can easily become hard to read exactly what the fourth or fifth
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
79 # question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That's done by replacing
5cd38ca David Heinemeier Hansson Added documentation about named bind variables
dhh authored
80 # the question marks with symbols and supplying a hash with values for the matching symbol keys:
81 #
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
82 # Company.where(
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
83 # "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
5cd38ca David Heinemeier Hansson Added documentation about named bind variables
dhh authored
84 # { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
85 # ).first
5cd38ca David Heinemeier Hansson Added documentation about named bind variables
dhh authored
86 #
c5ec16e David Heinemeier Hansson Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
87 # Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND
88 # operator. For instance:
89 #
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
90 # Student.where(:first_name => "Harvey", :status => 1)
91 # Student.where(params[:student])
c5ec16e David Heinemeier Hansson Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
92 #
2876707 Jeremy Kemper Pass a range in :conditions to use the SQL BETWEEN operator. Closes #697...
jeremy authored
93 # A range may be used in the hash to use the SQL BETWEEN operator:
94 #
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
95 # Student.where(:grade => 9..12)
c5ec16e David Heinemeier Hansson Added simple hash conditions to find that'll just convert hash to an AND...
dhh authored
96 #
aa4af60 Pratik Improve documentation.
lifo authored
97 # An array may be used in the hash to use the SQL IN operator:
98 #
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
99 # Student.where(:grade => [9,11,12])
aa4af60 Pratik Improve documentation.
lifo authored
100 #
e033b5d Pratik Merge docrails
lifo authored
101 # 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
102 # particular condition. For instance:
103 #
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
104 # Student.joins(:schools).where(:schools => { :type => 'public' })
105 # Student.joins(:schools).where('schools.type' => 'public' )
e033b5d Pratik Merge docrails
lifo authored
106 #
db045db David Heinemeier Hansson Initial
dhh authored
107 # == Overwriting default accessors
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
108 #
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
109 # All column values are automatically available through basic accessors on the Active Record object, but sometimes you
110 # want to specialize this behavior. This can be done by overwriting the default accessors (using the same
98dc582 Pratik Merge docrails.
lifo authored
111 # name as the attribute) and calling <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually change things.
db045db David Heinemeier Hansson Initial
dhh authored
112 # Example:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
113 #
db045db David Heinemeier Hansson Initial
dhh authored
114 # class Song < ActiveRecord::Base
115 # # Uses an integer of seconds to hold the length of the song
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
116 #
db045db David Heinemeier Hansson Initial
dhh authored
117 # def length=(minutes)
64092de Xavier Noria Improve documentation coverage and markup
fxn authored
118 # write_attribute(:length, minutes.to_i * 60)
db045db David Heinemeier Hansson Initial
dhh authored
119 # end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
120 #
db045db David Heinemeier Hansson Initial
dhh authored
121 # def length
0591c53 David Heinemeier Hansson Made the dynamic finders use the new find API and updated the examples h...
dhh authored
122 # read_attribute(:length) / 60
db045db David Heinemeier Hansson Initial
dhh authored
123 # end
124 # end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
125 #
98dc582 Pratik Merge docrails.
lifo authored
126 # You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt> instead of <tt>write_attribute(:attribute, value)</tt> and
127 # <tt>read_attribute(:attribute)</tt> as a shorter form.
0591c53 David Heinemeier Hansson Made the dynamic finders use the new find API and updated the examples h...
dhh authored
128 #
e4d845e Document automatically generated predicate methods for attributes. Close...
Marcel Molina authored
129 # == Attribute query methods
130 #
131 # In addition to the basic accessors, query methods are also automatically available on the Active Record object.
132 # Query methods allow you to test whether an attribute value is present.
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
133 #
e4d845e Document automatically generated predicate methods for attributes. Close...
Marcel Molina authored
134 # For example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call
135 # to determine whether the user has a name:
136 #
137 # user = User.new(:name => "David")
138 # user.name? # => true
139 #
140 # anonymous = User.new(:name => "")
141 # anonymous.name? # => false
142 #
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
143 # == Accessing attributes before they have been typecasted
4eab375 David Heinemeier Hansson Finished polishing API docs
dhh authored
144 #
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
145 # Sometimes you want to be able to read the raw attribute data without having the column-determined typecast run its course first.
dc4eec1 Pratik Merge docrails:
lifo authored
146 # That can be done by using the <tt><attribute>_before_type_cast</tt> accessors that all attributes have. For example, if your Account model
98dc582 Pratik Merge docrails.
lifo authored
147 # has a <tt>balance</tt> attribute, you can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.
4eab375 David Heinemeier Hansson Finished polishing API docs
dhh authored
148 #
149 # This is especially useful in validation situations where the user might supply a string for an integer field and you want to display
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
150 # the original string back in an error message. Accessing the attribute normally would typecast the string to 0, which isn't what you
4eab375 David Heinemeier Hansson Finished polishing API docs
dhh authored
151 # want.
152 #
ac8fd7d David Heinemeier Hansson Added dynamic attribute-based finders as a cleaner way of getting object...
dhh authored
153 # == Dynamic attribute-based finders
154 #
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
155 # Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL. They work by
6dc9173 David Heinemeier Hansson Missing doc updates
dhh authored
156 # 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>,
98dc582 Pratik Merge docrails.
lifo authored
157 # <tt>Person.find_all_by_last_name</tt>, and <tt>Payment.find_by_transaction_id</tt>. So instead of writing
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
158 # <tt>Person.where(:user_name => user_name).first</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
159 # And instead of writing <tt>Person.where(:last_name => last_name).all</tt>, you just do <tt>Person.find_all_by_last_name(last_name)</tt>.
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
160 #
ac8fd7d David Heinemeier Hansson Added dynamic attribute-based finders as a cleaner way of getting object...
dhh authored
161 # It's also possible to use multiple attributes in the same find by separating them with "_and_", so you get finders like
162 # <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
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
163 # <tt>Person.where(:user_name => user_name, :password => password).first</tt>, you just do
ac8fd7d David Heinemeier Hansson Added dynamic attribute-based finders as a cleaner way of getting object...
dhh authored
164 # <tt>Person.find_by_user_name_and_password(user_name, password)</tt>.
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
165 #
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
166 # It's even possible to call these dynamic finder methods on relations and named scopes. For example :
167 #
168 # Payment.order("created_on").find_all_by_amount(50)
169 # Payment.pending.find_last_by_amount(100)
959f362 David Heinemeier Hansson Added find_all style to the new dynamic finders
dhh authored
170 #
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
171 # The same dynamic finder style can be used to create the object if it doesn't already exist. This dynamic finder is called with
5c47ceb Michael Koziarski Typo fix in documentation from [9090] References #11422
NZKoz authored
172 # <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:
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
173 #
174 # # No 'Summer' tag exists
175 # Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
176 #
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
177 # # Now the 'Summer' tag does exist
178 # Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
179 #
c10b225 David Heinemeier Hansson Fixed that ActiveRecord#Base.find_or_create/initialize would not honor a...
dhh authored
180 # # Now 'Bob' exist and is an 'admin'
181 # User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }
182 #
0432d15 Pratik Merge with docrails.
lifo authored
183 # 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:
d19e464 Sam Stephenson Added find_or_initialize_by_X which works like find_or_create_by_X but d...
sstephenson authored
184 #
185 # # No 'Winter' tag exists
186 # winter = Tag.find_or_initialize_by_name("Winter")
85fbb22 David Heinemeier Hansson Backed out of new_record? to new? transformation as it would screw up ex...
dhh authored
187 # winter.new_record? # true
d19e464 Sam Stephenson Added find_or_initialize_by_X which works like find_or_create_by_X but d...
sstephenson authored
188 #
14cc8d2 Jeremy Kemper find_or_create_by_* takes a hash so you can create with more attributes ...
jeremy authored
189 # To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of
190 # a list of parameters. For example:
191 #
192 # Tag.find_or_create_by_name(:name => "rails", :creator => current_user)
193 #
194 # That will either find an existing tag named "rails", or create a new one while setting the user that created it.
195 #
098fa94 David Heinemeier Hansson Fixed documentation snafus #575, #576, #577, #585
dhh authored
196 # == Saving arrays, hashes, and other non-mappable objects in text columns
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
197 #
198 # 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+.
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
199 # This makes it possible to store arrays, hashes, and other non-mappable objects without doing any additional work. Example:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
200 #
db045db David Heinemeier Hansson Initial
dhh authored
201 # class User < ActiveRecord::Base
202 # serialize :preferences
203 # end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
204 #
ca2eb16 Fix syntax error in documentation. Closes #4679. [mislav@nippur.irb.hr]
Marcel Molina authored
205 # user = User.create(:preferences => { "background" => "black", "display" => large })
db045db David Heinemeier Hansson Initial
dhh authored
206 # User.find(user.id).preferences # => { "background" => "black", "display" => large }
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
207 #
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
208 # You can also specify a class option as the second parameter that'll raise an exception if a serialized object is retrieved as a
39e1ac6 Pratik Merge docrails
lifo authored
209 # descendant of a class not in the hierarchy. Example:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
210 #
db045db David Heinemeier Hansson Initial
dhh authored
211 # class User < ActiveRecord::Base
66f44e6 David Heinemeier Hansson Updated documentation for serialize
dhh authored
212 # serialize :preferences, Hash
db045db David Heinemeier Hansson Initial
dhh authored
213 # end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
214 #
0591c53 David Heinemeier Hansson Made the dynamic finders use the new find API and updated the examples h...
dhh authored
215 # user = User.create(:preferences => %w( one two three ))
db045db David Heinemeier Hansson Initial
dhh authored
216 # User.find(user.id).preferences # raises SerializationTypeMismatch
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
217 #
db045db David Heinemeier Hansson Initial
dhh authored
218 # == Single table inheritance
219 #
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
220 # Active Record allows inheritance by storing the name of the class in a column that by default is named "type" (can be changed
db045db David Heinemeier Hansson Initial
dhh authored
221 # by overwriting <tt>Base.inheritance_column</tt>). This means that an inheritance looking like this:
222 #
223 # class Company < ActiveRecord::Base; end
224 # class Firm < Company; end
225 # class Client < Company; end
226 # class PriorityClient < Client; end
227 #
98dc582 Pratik Merge docrails.
lifo authored
228 # When you do <tt>Firm.create(:name => "37signals")</tt>, this record will be saved in the companies table with type = "Firm". You can then
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
229 # fetch this row again using <tt>Company.where(:name => '37signals').first</tt> and it will return a Firm object.
db045db David Heinemeier Hansson Initial
dhh authored
230 #
f033833 David Heinemeier Hansson Improving documentation...
dhh authored
231 # 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
232 # like normal subclasses with no special magic for differentiating between them or reloading the right type with find.
233 #
db045db David Heinemeier Hansson Initial
dhh authored
234 # Note, all the attributes for all the cases are kept in the same table. Read more:
235 # http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
236 #
db045db David Heinemeier Hansson Initial
dhh authored
237 # == Connection to multiple databases in different models
238 #
239 # Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection.
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
240 # All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection.
98dc582 Pratik Merge docrails.
lifo authored
241 # For example, if Course is an ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
242 # and Course and all of its subclasses will use this connection instead.
db045db David Heinemeier Hansson Initial
dhh authored
243 #
244 # This feature is implemented by keeping a connection pool in ActiveRecord::Base that is a Hash indexed by the class. If a connection is
245 # requested, the retrieve_connection method will go up the class-hierarchy until a connection is found in the connection pool.
246 #
247 # == Exceptions
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
248 #
dc4eec1 Pratik Merge docrails:
lifo authored
249 # * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
250 # * AdapterNotSpecified - The configuration hash used in <tt>establish_connection</tt> didn't include an
db045db David Heinemeier Hansson Initial
dhh authored
251 # <tt>:adapter</tt> key.
dc4eec1 Pratik Merge docrails:
lifo authored
252 # * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a non-existent adapter
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
253 # (or a bad spelling of an existing one).
dc4eec1 Pratik Merge docrails:
lifo authored
254 # * AssociationTypeMismatch - The object assigned to the association wasn't of the type specified in the association definition.
255 # * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
256 # * ConnectionNotEstablished+ - No connection has been established. Use <tt>establish_connection</tt> before querying.
257 # * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist
258 # or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal
259 # nothing was found, please check its documentation for further details.
260 # * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
261 # * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
262 # <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of AttributeAssignmentError
d2fefbe David Heinemeier Hansson Added MultiparameterAssignmentErrors and AttributeAssignmentError except...
dhh authored
263 # objects that should be inspected to determine which attributes triggered the errors.
dc4eec1 Pratik Merge docrails:
lifo authored
264 # * AttributeAssignmentError - An error occurred while doing a mass assignment through the <tt>attributes=</tt> method.
d2fefbe David Heinemeier Hansson Added MultiparameterAssignmentErrors and AttributeAssignmentError except...
dhh authored
265 # You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error.
5707027 David Heinemeier Hansson Added better exception error when unknown column types are used with mig...
dhh authored
266 #
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
267 # *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
dc4eec1 Pratik Merge docrails:
lifo authored
268 # So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
db045db David Heinemeier Hansson Initial
dhh authored
269 # instances in the current object space.
270 class Base
0905396 Emilio Tagua construct_finder_sql now use Arel
miloops authored
271 ##
dbbae5e Pratik Merge with docrails
lifo authored
272 # :singleton-method:
db045db David Heinemeier Hansson Initial
dhh authored
273 # Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then passed
274 # on to any new database connections made and which can be retrieved on both a class and instance level by calling +logger+.
1a11bff risk danger olson Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
275 cattr_accessor :logger, :instance_writer => false
e694114 Jeremy Kemper Deprecation: removed Reloadable.
jeremy authored
276
db045db David Heinemeier Hansson Initial
dhh authored
277 def self.inherited(child) #:nodoc:
278 @@subclasses[self] ||= []
279 @@subclasses[self] << child
280 super
281 end
e694114 Jeremy Kemper Deprecation: removed Reloadable.
jeremy authored
282
fed7d33 David Heinemeier Hansson Fixed documentation
dhh authored
283 def self.reset_subclasses #:nodoc:
bfbf6bb Jamis Buck Allow ARStore::Session to indicate that it should not be reloaded in dev...
jamis authored
284 nonreloadables = []
e7f61ea Jamis Buck squash the memleak in dev mode finally (fingers crossed, here)
jamis authored
285 subclasses.each do |klass|
c08547d Joshua Peek Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under Ac...
josh authored
286 unless ActiveSupport::Dependencies.autoloaded? klass
bfbf6bb Jamis Buck Allow ARStore::Session to indicate that it should not be reloaded in dev...
jamis authored
287 nonreloadables << klass
288 next
289 end
e7f61ea Jamis Buck squash the memleak in dev mode finally (fingers crossed, here)
jamis authored
290 klass.instance_variables.each { |var| klass.send(:remove_instance_variable, var) }
291 klass.instance_methods(false).each { |m| klass.send :undef_method, m }
292 end
bfbf6bb Jamis Buck Allow ARStore::Session to indicate that it should not be reloaded in dev...
jamis authored
293 @@subclasses = {}
294 nonreloadables.each { |klass| (@@subclasses[klass.superclass] ||= []) << klass }
3c0129a David Heinemeier Hansson Fixed memory leak with Active Record classes when Dependencies.mechanism...
dhh authored
295 end
296
db045db David Heinemeier Hansson Initial
dhh authored
297 @@subclasses = {}
c3aa2bc Manfred Stienstra Ensure nested with_scope merges conditions inside out [#2193 state:resol...
Manfred authored
298
dbbae5e Pratik Merge with docrails
lifo authored
299 ##
300 # :singleton-method:
a293278 Pratik Merge docrails
lifo authored
301 # Contains the database configuration - as is typically stored in config/database.yml -
302 # as a Hash.
303 #
304 # For example, the following database.yml...
0905396 Emilio Tagua construct_finder_sql now use Arel
miloops authored
305 #
a293278 Pratik Merge docrails
lifo authored
306 # development:
307 # adapter: sqlite3
308 # database: db/development.sqlite3
0905396 Emilio Tagua construct_finder_sql now use Arel
miloops authored
309 #
a293278 Pratik Merge docrails
lifo authored
310 # production:
311 # adapter: sqlite3
312 # database: db/production.sqlite3
313 #
314 # ...would result in ActiveRecord::Base.configurations to look like this:
315 #
316 # {
317 # 'development' => {
318 # 'adapter' => 'sqlite3',
319 # 'database' => 'db/development.sqlite3'
320 # },
321 # 'production' => {
322 # 'adapter' => 'sqlite3',
323 # 'database' => 'db/production.sqlite3'
324 # }
325 # }
1a11bff risk danger olson Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
326 cattr_accessor :configurations, :instance_writer => false
c4a3634 Jeremy Kemper Corrected @@configurations typo. #1410 [david@ruppconsulting.com]
jeremy authored
327 @@configurations = {}
328
dbbae5e Pratik Merge with docrails
lifo authored
329 ##
330 # :singleton-method:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
331 # Accessor for the prefix type that will be prepended to every primary key column name. The options are :table_name and
db045db David Heinemeier Hansson Initial
dhh authored
332 # :table_name_with_underscore. If the first is specified, the Product class will look for "productid" instead of "id" as
333 # the primary column. If the latter is specified, the Product class will look for "product_id" instead of "id". Remember
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
334 # that this is a global setting for all Active Records.
1a11bff risk danger olson Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
335 cattr_accessor :primary_key_prefix_type, :instance_writer => false
db045db David Heinemeier Hansson Initial
dhh authored
336 @@primary_key_prefix_type = nil
337
dbbae5e Pratik Merge with docrails
lifo authored
338 ##
339 # :singleton-method:
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
340 # Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all
098fa94 David Heinemeier Hansson Fixed documentation snafus #575, #576, #577, #585
dhh authored
341 # table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace
db045db David Heinemeier Hansson Initial
dhh authored
342 # for tables in a shared database. By default, the prefix is the empty string.
67d1cec Andrew White Add the ability to specify table_name_prefix on individual modules
pixeltrix authored
343 #
344 # If you are organising your models within modules you can add a prefix to the models within a namespace by defining
345 # a singleton method in the parent module called table_name_prefix which returns your chosen prefix.
bab1f91 Phil Smith table_name_prefix and table_name_suffix are class_attributes instead of ...
phs authored
346 class_attribute :table_name_prefix, :instance_writer => false
347 self.table_name_prefix = ""
db045db David Heinemeier Hansson Initial
dhh authored
348
dbbae5e Pratik Merge with docrails
lifo authored
349 ##
350 # :singleton-method:
db045db David Heinemeier Hansson Initial
dhh authored
351 # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
352 # "people_basecamp"). By default, the suffix is the empty string.
bab1f91 Phil Smith table_name_prefix and table_name_suffix are class_attributes instead of ...
phs authored
353 class_attribute :table_name_suffix, :instance_writer => false
354 self.table_name_suffix = ""
db045db David Heinemeier Hansson Initial
dhh authored
355
dbbae5e Pratik Merge with docrails
lifo authored
356 ##
357 # :singleton-method:
84a14f2 Jeremy Kemper Raise ProtectedAttributeAssignmentError in development and test environm...
jeremy authored
358 # Indicates whether table names should be the pluralized versions of the corresponding class names.
98dc582 Pratik Merge docrails.
lifo authored
359 # If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
db045db David Heinemeier Hansson Initial
dhh authored
360 # See table_name for the full rules on table/class naming. This is true, by default.
1a11bff risk danger olson Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
361 cattr_accessor :pluralize_table_names, :instance_writer => false
db045db David Heinemeier Hansson Initial
dhh authored
362 @@pluralize_table_names = true
363
dbbae5e Pratik Merge with docrails
lifo authored
364 ##
365 # :singleton-method:
60de8c1 David Heinemeier Hansson Added Base.default_timezone accessor that determines whether to use Time...
dhh authored
366 # Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates and times from the database.
367 # This is set to :local by default.
1a11bff risk danger olson Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
368 cattr_accessor :default_timezone, :instance_writer => false
60de8c1 David Heinemeier Hansson Added Base.default_timezone accessor that determines whether to use Time...
dhh authored
369 @@default_timezone = :local
d8641ca Jeremy Kemper CHANGED DEFAULT: set ActiveRecord::Base.allow_concurrency to false. Mos...
jeremy authored
370
dbbae5e Pratik Merge with docrails
lifo authored
371 ##
372 # :singleton-method:
24c3599 Sam Stephenson Support using different database adapters for development and test with ...
sstephenson authored
373 # Specifies the format to use when dumping the database schema with Rails'
374 # Rakefile. If :sql, the schema is dumped as (potentially database-
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
375 # specific) SQL statements. If :ruby, the schema is dumped as an
24c3599 Sam Stephenson Support using different database adapters for development and test with ...
sstephenson authored
376 # ActiveRecord::Schema file which can be loaded into any database that
377 # supports migrations. Use :ruby if you want to have different database
378 # adapters for, e.g., your development and test environments.
1a11bff risk danger olson Don't create instance writer methods for class attributes. Closes #7401...
technoweenie authored
379 cattr_accessor :schema_format , :instance_writer => false
660952e David Heinemeier Hansson CHANGED DEFAULT: ActiveRecord::Base.schema_format is now :ruby by defaul...
dhh authored
380 @@schema_format = :ruby
3b0e1d9 Joshua Peek Prefer string core_ext inflector methods over directly accessing Inflect...
josh authored
381
dbbae5e Pratik Merge with docrails
lifo authored
382 ##
383 # :singleton-method:
155f0be Rizwan Reza Changes migration number to version due to ambiguity. [#3065 state:commi...
rizwanreza authored
384 # Specify whether or not to use timestamps for migration versions
bbab639 Nik Wakelin Set config.active_record.timestamped_migrations = false to have migratio...
nikz authored
385 cattr_accessor :timestamped_migrations , :instance_writer => false
386 @@timestamped_migrations = true
387
bca8751 Rodrigo Kochenburger Add ActiveRecord option to store the full class name on STI's type colum...
divoxx authored
388 # Determine whether to store the full constant name including namespace when using STI
389 superclass_delegating_accessor :store_full_sti_class
1459c8c David Heinemeier Hansson Changed ActiveRecord::Base.store_full_sti_class to be true by default re...
dhh authored
390 self.store_full_sti_class = true
3b0e1d9 Joshua Peek Prefer string core_ext inflector methods over directly accessing Inflect...
josh authored
391
2530d0e Pratik Added default_scope to Base [#1381 state:committed] (Paweł Kondzior)
lifo authored
392 # Stores the default scope for the class
393 class_inheritable_accessor :default_scoping, :instance_writer => false
394 self.default_scoping = []
395
db045db David Heinemeier Hansson Initial
dhh authored
396 class << self # Class methods
8d78a82 José Valim Deprecate ActiveRecord::Base.colorize_logging.
josevalim authored
397 def colorize_logging(*args)
398 ActiveSupport::Deprecation.warn "ActiveRecord::Base.colorize_logging and " <<
39d6f9e Yehuda Katz Make many parts of Rails lazy. In order to facilitate this,
wycats authored
399 "config.active_record.colorize_logging are deprecated. Please use " <<
f0523f7 Prem Sichanugrist Rename Rails::Subscriber to Rails::LogSubscriber
sikachu authored
400 "Rails::LogSubscriber.colorize_logging or config.colorize_logging instead", caller
8d78a82 José Valim Deprecate ActiveRecord::Base.colorize_logging.
josevalim authored
401 end
402 alias :colorize_logging= :colorize_logging
403
8d31c9f Pratik Move update and update_all to Relation
lifo authored
404 delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :update, :update_all, :to => :scoped
dc3cc6c Pratik Move batch finders to Relation
lifo authored
405 delegate :find_each, :find_in_batches, :to => :scoped
6f5f23a Pratik Add Relation#includes to be an equivalent of current finder option :incl...
lifo authored
406 delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped
9465b84 Pratik Rename CalculationMethods to Calculations and get rid of the old Calcula...
lifo authored
407 delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped
a7fd564 Pratik Add Model.select/group/order/limit/joins/conditions/preload/eager_load c...
lifo authored
408
98dc582 Pratik Merge docrails.
lifo authored
409 # Executes a custom SQL query against your database and returns all the results. The results will
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
410 # be returned as an array with columns requested encapsulated as attributes of the model you call
a293278 Pratik Merge docrails
lifo authored
411 # this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
412 # a Product object with the attributes you specified in the SQL query.
edf32ce More complete documentation for find_by_sql. Closes #7912 [fearoffish]
Marcel Molina authored
413 #
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
414 # If you call a complicated SQL query which spans multiple tables the columns specified by the
415 # SELECT will be attributes of the model, whether or not they are columns of the corresponding
edf32ce More complete documentation for find_by_sql. Closes #7912 [fearoffish]
Marcel Molina authored
416 # table.
417 #
98dc582 Pratik Merge docrails.
lifo authored
418 # The +sql+ parameter is a full SQL query as a string. It will be called as is, there will be
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
419 # no database agnostic conversions performed. This should be a last resort because using, for example,
420 # MySQL specific terms will lock you to using that particular database engine or require you to
a293278 Pratik Merge docrails
lifo authored
421 # change your call if you switch engines.
edf32ce More complete documentation for find_by_sql. Closes #7912 [fearoffish]
Marcel Molina authored
422 #
423 # ==== Examples
98dc582 Pratik Merge docrails.
lifo authored
424 # # A simple SQL query spanning multiple tables
edf32ce More complete documentation for find_by_sql. Closes #7912 [fearoffish]
Marcel Molina authored
425 # Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
426 # > [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
427 #
428 # # You can use the same string replacement techniques as you can with ActiveRecord#find
429 # Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
430 # > [#<Post:0x36bff9c @attributes={"first_name"=>"The Cheap Man Buys Twice"}>, ...]
db045db David Heinemeier Hansson Initial
dhh authored
431 def find_by_sql(sql)
6e3d2a7 Jeremy Kemper Revert "Performance: freeze cached rows instead of duping"
jeremy authored
432 connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) }
db045db David Heinemeier Hansson Initial
dhh authored
433 end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
434
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
435 # Creates an object (or multiple objects) and saves it to the database, if validations pass.
a23bea7 Document API for create's attributes parameter and provide examples. Clo...
Marcel Molina authored
436 # The resulting object is returned whether the object was saved successfully to the database or not.
437 #
438 # The +attributes+ parameter can be either be a Hash or an Array of Hashes. These Hashes describe the
439 # attributes on the objects that are to be created.
440 #
441 # ==== Examples
442 # # Create a single new object
443 # User.create(:first_name => 'Jamie')
dd120ed David Heinemeier Hansson Added block-setting of attributes for Base.create like Base.new already ...
dhh authored
444 #
a23bea7 Document API for create's attributes parameter and provide examples. Clo...
Marcel Molina authored
445 # # Create an Array of new objects
dc4eec1 Pratik Merge docrails:
lifo authored
446 # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
dd120ed David Heinemeier Hansson Added block-setting of attributes for Base.create like Base.new already ...
dhh authored
447 #
448 # # Create a single object and pass it into a block to set other attributes.
449 # User.create(:first_name => 'Jamie') do |u|
450 # u.is_admin = false
451 # end
452 #
453 # # Creating an Array of new objects using a block, where the block is executed for each object:
dc4eec1 Pratik Merge docrails:
lifo authored
454 # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
dd120ed David Heinemeier Hansson Added block-setting of attributes for Base.create like Base.new already ...
dhh authored
455 # u.is_admin = false
3b0e1d9 Joshua Peek Prefer string core_ext inflector methods over directly accessing Inflect...
josh authored
456 # end
dd120ed David Heinemeier Hansson Added block-setting of attributes for Base.create like Base.new already ...
dhh authored
457 def create(attributes = nil, &block)
efa81da David Heinemeier Hansson Added the option of supplying an array of ids and attributes to Base#upd...
dhh authored
458 if attributes.is_a?(Array)
dd120ed David Heinemeier Hansson Added block-setting of attributes for Base.create like Base.new already ...
dhh authored
459 attributes.collect { |attr| create(attr, &block) }
efa81da David Heinemeier Hansson Added the option of supplying an array of ids and attributes to Base#upd...
dhh authored
460 else
461 object = new(attributes)
dd120ed David Heinemeier Hansson Added block-setting of attributes for Base.create like Base.new already ...
dhh authored
462 yield(object) if block_given?
efa81da David Heinemeier Hansson Added the option of supplying an array of ids and attributes to Base#upd...
dhh authored
463 object.save
464 object
465 end
db045db David Heinemeier Hansson Initial
dhh authored
466 end
467
468 # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
469 # The use of this method should be restricted to complicated SQL queries that can't be executed
ee614d6 Add documentation caveat about when to use count_by_sql. Closes #8090. [...
Marcel Molina authored
470 # using the ActiveRecord::Calculations class methods. Look into those before using this.
471 #
a293278 Pratik Merge docrails
lifo authored
472 # ==== Parameters
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
473 #
dc4eec1 Pratik Merge docrails:
lifo authored
474 # * +sql+ - An SQL statement which should return a count query from the database, see the example below.
ee614d6 Add documentation caveat about when to use count_by_sql. Closes #8090. [...
Marcel Molina authored
475 #
476 # ==== Examples
477 #
e17bf81 Jamis Buck Fix typo in count_by_sql documentation #1969 [Alexey Verkhovsky]
jamis authored
478 # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
db045db David Heinemeier Hansson Initial
dhh authored
479 def count_by_sql(sql)
a775cb1 David Heinemeier Hansson Added the option for sanitizing find_by_sql and the offset parts in regu...
dhh authored
480 sql = sanitize_conditions(sql)
caaf40d David Heinemeier Hansson Added AbstractAdapter#select_value and AbstractAdapter#select_values as ...
dhh authored
481 connection.select_value(sql, "#{name} Count").to_i
db045db David Heinemeier Hansson Initial
dhh authored
482 end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
483
98dc582 Pratik Merge docrails.
lifo authored
484 # Attributes named in this macro are protected from mass-assignment,
485 # such as <tt>new(attributes)</tt>,
486 # <tt>update_attributes(attributes)</tt>, or
487 # <tt>attributes=(attributes)</tt>.
488 #
489 # Mass-assignment to these attributes will simply be ignored, to assign
490 # to them you can use direct writer methods. This is meant to protect
491 # sensitive attributes from being overwritten by malicious users
492 # tampering with URLs or forms.
db045db David Heinemeier Hansson Initial
dhh authored
493 #
494 # class Customer < ActiveRecord::Base
495 # attr_protected :credit_rating
496 # end
497 #
498 # customer = Customer.new("name" => David, "credit_rating" => "Excellent")
499 # customer.credit_rating # => nil
500 # customer.attributes = { "description" => "Jolly fellow", "credit_rating" => "Superb" }
501 # customer.credit_rating # => nil
502 #
503 # customer.credit_rating = "Average"
504 # customer.credit_rating # => "Average"
d761ac4 Add docs explaining how to protect all attributes using attr_accessible ...
Marcel Molina authored
505 #
98dc582 Pratik Merge docrails.
lifo authored
506 # To start from an all-closed default and enable attributes as needed,
507 # have a look at +attr_accessible+.
e033b5d Pratik Merge docrails
lifo authored
508 #
509 # If the access logic of your application is richer you can use <tt>Hash#except</tt>
510 # or <tt>Hash#slice</tt> to sanitize the hash of parameters before they are
511 # passed to Active Record.
31c8353 Emilio Tagua Don't use local vars before testing its conditional.
miloops authored
512 #
e033b5d Pratik Merge docrails
lifo authored
513 # For example, it could be the case that the list of protected attributes
514 # for a given model depends on the role of the user:
515 #
516 # # Assumes plan_id is not protected because it depends on the role.
517 # params[:account] = params[:account].except(:plan_id) unless admin?
518 # @account.update_attributes(params[:account])
519 #
520 # Note that +attr_protected+ is still applied to the received hash. Thus,
521 # with this technique you can at most _extend_ the list of protected
522 # attributes for a particular mass-assignment call.
db045db David Heinemeier Hansson Initial
dhh authored
523 def attr_protected(*attributes)
b6bac73 Merge commit 'origin/master'
Yehuda Katz + Carl Lerche authored
524 write_inheritable_attribute(:attr_protected, Set.new(attributes.map {|a| a.to_s}) + (protected_attributes || []))
db045db David Heinemeier Hansson Initial
dhh authored
525 end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
526
098fa94 David Heinemeier Hansson Fixed documentation snafus #575, #576, #577, #585
dhh authored
527 # Returns an array of all the attributes that have been protected from mass-assignment.
db045db David Heinemeier Hansson Initial
dhh authored
528 def protected_attributes # :nodoc:
288e947 Clemens Kofler Some performance goodness for inheritable attributes.
clemens authored
529 read_inheritable_attribute(:attr_protected)
db045db David Heinemeier Hansson Initial
dhh authored
530 end
531
98dc582 Pratik Merge docrails.
lifo authored
532 # Specifies a white list of model attributes that can be set via
533 # mass-assignment, such as <tt>new(attributes)</tt>,
534 # <tt>update_attributes(attributes)</tt>, or
535 # <tt>attributes=(attributes)</tt>
f770b82 Enhance explanation with more examples for attr_accessible macro. Closes...
Marcel Molina authored
536 #
98dc582 Pratik Merge docrails.
lifo authored
537 # This is the opposite of the +attr_protected+ macro: Mass-assignment
538 # will only set attributes in this list, to assign to the rest of
539 # attributes you can use direct writer methods. This is meant to protect
540 # sensitive attributes from being overwritten by malicious users
541 # tampering with URLs or forms. If you'd rather start from an all-open
542 # default and restrict attributes as needed, have a look at
543 # +attr_protected+.
d761ac4 Add docs explaining how to protect all attributes using attr_accessible ...
Marcel Molina authored
544 #
545 # class Customer < ActiveRecord::Base
f770b82 Enhance explanation with more examples for attr_accessible macro. Closes...
Marcel Molina authored
546 # attr_accessible :name, :nickname
d761ac4 Add docs explaining how to protect all attributes using attr_accessible ...
Marcel Molina authored
547 # end
548 #
f770b82 Enhance explanation with more examples for attr_accessible macro. Closes...
Marcel Molina authored
549 # customer = Customer.new(:name => "David", :nickname => "Dave", :credit_rating => "Excellent")
550 # customer.credit_rating # => nil
551 # customer.attributes = { :name => "Jolly fellow", :credit_rating => "Superb" }
552 # customer.credit_rating # => nil
d761ac4 Add docs explaining how to protect all attributes using attr_accessible ...
Marcel Molina authored
553 #
f770b82 Enhance explanation with more examples for attr_accessible macro. Closes...
Marcel Molina authored
554 # customer.credit_rating = "Average"
555 # customer.credit_rating # => "Average"
e033b5d Pratik Merge docrails
lifo authored
556 #
557 # If the access logic of your application is richer you can use <tt>Hash#except</tt>
558 # or <tt>Hash#slice</tt> to sanitize the hash of parameters before they are
559 # passed to Active Record.
31c8353 Emilio Tagua Don't use local vars before testing its conditional.
miloops authored
560 #
e033b5d Pratik Merge docrails
lifo authored
561 # For example, it could be the case that the list of accessible attributes
562 # for a given model depends on the role of the user:
563 #
564 # # Assumes plan_id is accessible because it depends on the role.
565 # params[:account] = params[:account].except(:plan_id) unless admin?
566 # @account.update_attributes(params[:account])
567 #
568 # Note that +attr_accessible+ is still applied to the received hash. Thus,
569 # with this technique you can at most _narrow_ the list of accessible
570 # attributes for a particular mass-assignment call.
db045db David Heinemeier Hansson Initial
dhh authored
571 def attr_accessible(*attributes)
288e947 Clemens Kofler Some performance goodness for inheritable attributes.
clemens authored
572 write_inheritable_attribute(:attr_accessible, Set.new(attributes.map(&:to_s)) + (accessible_attributes || []))
db045db David Heinemeier Hansson Initial
dhh authored
573 end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
574
098fa94 David Heinemeier Hansson Fixed documentation snafus #575, #576, #577, #585
dhh authored
575 # Returns an array of all the attributes that have been made accessible to mass-assignment.
db045db David Heinemeier Hansson Initial
dhh authored
576 def accessible_attributes # :nodoc:
288e947 Clemens Kofler Some performance goodness for inheritable attributes.
clemens authored
577 read_inheritable_attribute(:attr_accessible)
db045db David Heinemeier Hansson Initial
dhh authored
578 end
579
66d05f5 risk danger olson Add attr_readonly to specify columns that are skipped during a normal Ac...
technoweenie authored
580 # Attributes listed as readonly can be set for a new record, but will be ignored in database updates afterwards.
581 def attr_readonly(*attributes)
288e947 Clemens Kofler Some performance goodness for inheritable attributes.
clemens authored
582 write_inheritable_attribute(:attr_readonly, Set.new(attributes.map(&:to_s)) + (readonly_attributes || []))
66d05f5 risk danger olson Add attr_readonly to specify columns that are skipped during a normal Ac...
technoweenie authored
583 end
584
585 # Returns an array of all the attributes that have been specified as readonly.
586 def readonly_attributes
5b61168 Emilio Tagua Added arel_attributes_values methods, refactored locking and AR#update t...
miloops authored
587 read_inheritable_attribute(:attr_readonly) || []
66d05f5 risk danger olson Add attr_readonly to specify columns that are skipped during a normal Ac...
technoweenie authored
588 end
c450a36 David Heinemeier Hansson Doc fixes
dhh authored
589
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
590 # If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object,
591 # then specify the name of that attribute using this method and it will be handled automatically.
592 # The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that
98dc582 Pratik Merge docrails.
lifo authored
593 # class on retrieval or SerializationTypeMismatch will be raised.
1a0cdf7 David Heinemeier Hansson Docfix (closes #8096)
dhh authored
594 #
a293278 Pratik Merge docrails
lifo authored
595 # ==== Parameters
1a0cdf7 David Heinemeier Hansson Docfix (closes #8096)
dhh authored
596 #
dc4eec1 Pratik Merge docrails:
lifo authored
597 # * +attr_name+ - The field name that should be serialized.
598 # * +class_name+ - Optional, class name that the object type should be equal to.
1a0cdf7 David Heinemeier Hansson Docfix (closes #8096)
dhh authored
599 #
600 # ==== Example
601 # # Serialize a preferences attribute
602 # class User
603 # serialize :preferences
604 # end
db045db David Heinemeier Hansson Initial
dhh authored
605 def serialize(attr_name, class_name = Object)
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
606 serialized_attributes[attr_name.to_s] = class_name
db045db David Heinemeier Hansson Initial
dhh authored
607 end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
608
db045db David Heinemeier Hansson Initial
dhh authored
609 # Returns a hash of all the attributes that have been specified for serialization as keys and their class restriction as values.
610 def serialized_attributes
288e947 Clemens Kofler Some performance goodness for inheritable attributes.
clemens authored
611 read_inheritable_attribute(:attr_serialized) or write_inheritable_attribute(:attr_serialized, {})
db045db David Heinemeier Hansson Initial
dhh authored
612 end
613
614 # Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending
98dc582 Pratik Merge docrails.
lifo authored
615 # directly from ActiveRecord::Base. So if the hierarchy looks like: Reply < Message < ActiveRecord::Base, then Message is used
d64832c Give examples for what tables should be called for models inside a modul...
Marcel Molina authored
616 # to guess the table name even when called on Reply. The rules used to do the guess are handled by the Inflector class
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
617 # in Active Support, which knows almost all common English inflections. You can add new inflections in config/initializers/inflections.rb.
db045db David Heinemeier Hansson Initial
dhh authored
618 #
14101c7 Jeremy Kemper Nested classes are given table names prefixed by the singular form of th...
jeremy authored
619 # Nested classes are given table names prefixed by the singular form of
98dc582 Pratik Merge docrails.
lifo authored
620 # the parent's table name. Enclosing modules are not considered.
621 #
622 # ==== Examples
d64832c Give examples for what tables should be called for models inside a modul...
Marcel Molina authored
623 #
624 # class Invoice < ActiveRecord::Base; end;
14101c7 Jeremy Kemper Nested classes are given table names prefixed by the singular form of th...
jeremy authored
625 # file class table_name
626 # invoice.rb Invoice invoices
d64832c Give examples for what tables should be called for models inside a modul...
Marcel Molina authored
627 #
628 # class Invoice < ActiveRecord::Base; class Lineitem < ActiveRecord::Base; end; end;
629 # file class table_name
630 # invoice.rb Invoice::Lineitem invoice_lineitems
631 #
632 # module Invoice; class Lineitem < ActiveRecord::Base; end; end;
633 # file class table_name
634 # invoice/lineitem.rb Invoice::Lineitem lineitems
db045db David Heinemeier Hansson Initial
dhh authored
635 #
98dc582 Pratik Merge docrails.
lifo authored
636 # Additionally, the class-level +table_name_prefix+ is prepended and the
637 # +table_name_suffix+ is appended. So if you have "myapp_" as a prefix,
14101c7 Jeremy Kemper Nested classes are given table names prefixed by the singular form of th...
jeremy authored
638 # the table name guess for an Invoice class becomes "myapp_invoices".
639 # Invoice::Lineitem becomes "myapp_invoice_lineitems".
640 #
641 # You can also overwrite this class method to allow for unguessable
642 # links, such as a Mouse class with a link to a "mice" table. Example:
db045db David Heinemeier Hansson Initial
dhh authored
643 #
644 # class Mouse < ActiveRecord::Base
14101c7 Jeremy Kemper Nested classes are given table names prefixed by the singular form of th...
jeremy authored
645 # set_table_name "mice"
db045db David Heinemeier Hansson Initial
dhh authored
646 # end
dcc4868 David Heinemeier Hansson Fixed that Base.table_name would expect a parameter when used in has_and...
dhh authored
647 def table_name
d736568 Speed up the setting of table_name. Closes #2428.
Marcel Molina authored
648 reset_table_name
649 end
650
8d82bef Thiago Pradi Documentation for #quoted_table_name method
tchandy authored
651 # Returns a quoted version of the table name, used to construct SQL statements.
798d282 Pratik Cache quoted_table_name
lifo authored
652 def quoted_table_name
653 @quoted_table_name ||= connection.quote_table_name(table_name)
654 end
655
4a8c880 Xavier Noria refactors AR::Base#reset_table_name
fxn authored
656 # Computes the table name, (re)sets it internally, and returns it.
fed7d33 David Heinemeier Hansson Fixed documentation
dhh authored
657 def reset_table_name #:nodoc:
4a8c880 Xavier Noria refactors AR::Base#reset_table_name
fxn authored
658 self.table_name = compute_table_name
db045db David Heinemeier Hansson Initial
dhh authored
659 end
660
5f7bc47 Yehuda Katz Rename modularized_table_name_prefix to full_table_name_prefix [#4032 st...
wycats authored
661 def full_table_name_prefix #:nodoc:
67d1cec Andrew White Add the ability to specify table_name_prefix on individual modules
pixeltrix authored
662 (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
663 end
664
9d2da04 Jeremy Kemper Cache inheritance_column. Closes #6592.
jeremy authored
665 # Defines the column name for use with single table inheritance
666 # -- can be set in subclasses like so: self.inheritance_column = "type_id"
db045db David Heinemeier Hansson Initial
dhh authored
667 def inheritance_column
9d2da04 Jeremy Kemper Cache inheritance_column. Closes #6592.
jeremy authored
668 @inheritance_column ||= "type".freeze
db045db David Heinemeier Hansson Initial
dhh authored
669 end
670
7c8f3ed Jeremy Kemper r4325@asus: jeremy | 2005-11-12 03:57:46 -0800
jeremy authored
671 # Lazy-set the sequence name to the connection's default. This method
672 # is only ever called once since set_sequence_name overrides it.
fed7d33 David Heinemeier Hansson Fixed documentation
dhh authored
673 def sequence_name #:nodoc:
7c8f3ed Jeremy Kemper r4325@asus: jeremy | 2005-11-12 03:57:46 -0800
jeremy authored
674 reset_sequence_name
675 end
676
fed7d33 David Heinemeier Hansson Fixed documentation
dhh authored
677 def reset_sequence_name #:nodoc:
7c8f3ed Jeremy Kemper r4325@asus: jeremy | 2005-11-12 03:57:46 -0800
jeremy authored
678 default = connection.default_sequence_name(table_name, primary_key)
679 set_sequence_name(default)
680 default
14ea312 David Heinemeier Hansson Made Oracle a first-class connection adapter by adhering closer to idiom...
dhh authored
681 end
682
1aa82b3 David Heinemeier Hansson Added keyword-style approach to defining the custom relational bindings ...
dhh authored
683 # Sets the table name to use to the given value, or (if the value
4eab375 David Heinemeier Hansson Finished polishing API docs
dhh authored
684 # is nil or false) to the value returned by the given block.
1aa82b3 David Heinemeier Hansson Added keyword-style approach to defining the custom relational bindings ...
dhh authored
685 #
686 # class Project < ActiveRecord::Base
687 # set_table_name "project"
688 # end
c9c1852 David Heinemeier Hansson Making ActiveRecord faster [skaes]
dhh authored
689 def set_table_name(value = nil, &block)
47c9a35 Santiago Pastorino Reset quoted_table_name after set_table_name [#4568 state:resolved]
spastorino authored
690 @quoted_table_name = nil
1aa82b3 David Heinemeier Hansson Added keyword-style approach to defining the custom relational bindings ...
dhh authored
691 define_attr_method :table_name, value, &block
692 end
693 alias :table_name= :set_table_name
694
695 # Sets the name of the inheritance column to use to the given value,
696 # or (if the value # is nil or false) to the value returned by the
4eab375 David Heinemeier Hansson Finished polishing API docs
dhh authored
697 # given block.
1aa82b3 David Heinemeier Hansson Added keyword-style approach to defining the custom relational bindings ...
dhh authored
698 #
699 # class Project < ActiveRecord::Base
700 # set_inheritance_column do
701 # original_inheritance_column + "_id"
702 # end
703 # end
c9c1852 David Heinemeier Hansson Making ActiveRecord faster [skaes]
dhh authored
704 def set_inheritance_column(value = nil, &block)
1aa82b3 David Heinemeier Hansson Added keyword-style approach to defining the custom relational bindings ...
dhh authored
705 define_attr_method :inheritance_column, value, &block
706 end
707 alias :inheritance_column= :set_inheritance_column
708
14ea312 David Heinemeier Hansson Made Oracle a first-class connection adapter by adhering closer to idiom...
dhh authored
709 # Sets the name of the sequence to use when generating ids to the given
710 # value, or (if the value is nil or false) to the value returned by the
7117fdb Jeremy Kemper r3616@asus: jeremy | 2005-09-26 23:09:28 -0700
jeremy authored
711 # given block. This is required for Oracle and is useful for any
712 # database which relies on sequences for primary key generation.
14ea312 David Heinemeier Hansson Made Oracle a first-class connection adapter by adhering closer to idiom...
dhh authored
713 #
2076dca Jeremy Kemper r3095@asus: jeremy | 2005-11-15 22:40:51 -0800
jeremy authored
714 # If a sequence name is not explicitly set when using Oracle or Firebird,
715 # it will default to the commonly used pattern of: #{table_name}_seq
716 #
717 # If a sequence name is not explicitly set when using PostgreSQL, it
718 # will discover the sequence corresponding to your primary key for you.
14ea312 David Heinemeier Hansson Made Oracle a first-class connection adapter by adhering closer to idiom...
dhh authored
719 #
720 # class Project < ActiveRecord::Base
721 # set_sequence_name "projectseq" # default would have been "project_seq"
722 # end
c9c1852 David Heinemeier Hansson Making ActiveRecord faster [skaes]
dhh authored
723 def set_sequence_name(value = nil, &block)
14ea312 David Heinemeier Hansson Made Oracle a first-class connection adapter by adhering closer to idiom...
dhh authored
724 define_attr_method :sequence_name, value, &block
725 end
726 alias :sequence_name= :set_sequence_name
727
db045db David Heinemeier Hansson Initial
dhh authored
728 # Turns the +table_name+ back into a class name following the reverse rules of +table_name+.
729 def class_name(table_name = table_name) # :nodoc:
730 # remove any prefix and/or suffix from the table name
81737fc Jeremy Kemper r1613@asus: jeremy | 2005-07-03 07:04:53 -0700
jeremy authored
731 class_name = table_name[table_name_prefix.length..-(table_name_suffix.length + 1)].camelize
732 class_name = class_name.singularize if pluralize_table_names
733 class_name
db045db David Heinemeier Hansson Initial
dhh authored
734 end
735
816f37a David Heinemeier Hansson Added migration support to SQL Server adapter (please someone do the sam...
dhh authored
736 # Indicates whether the table associated with this class exists
737 def table_exists?
8877ab5 Tarmo Tänav Added AbstractAdapter#table_exists? and made AbstractAdapter#table imple...
tarmo authored
738 connection.table_exists?(table_name)
816f37a David Heinemeier Hansson Added migration support to SQL Server adapter (please someone do the sam...
dhh authored
739 end
740
db045db David Heinemeier Hansson Initial
dhh authored
741 # Returns an array of column objects for the table associated with this class.
742 def columns
8b5f4e4 Jeremy Kemper Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized inst...
jeremy authored
743 unless defined?(@columns) && @columns
c0899bc Add convenience predicate methods on Column class. In partial fullfilmen...
Marcel Molina authored
744 @columns = connection.columns(table_name, "#{name} Columns")
8b5f4e4 Jeremy Kemper Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized inst...
jeremy authored
745 @columns.each { |column| column.primary = column.name == primary_key }
c0899bc Add convenience predicate methods on Column class. In partial fullfilmen...
Marcel Molina authored
746 end
747 @columns
db045db David Heinemeier Hansson Initial
dhh authored
748 end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
749
3b4450b Michael Koziarski Docs fix for columns_hash [bradediger]
NZKoz authored
750 # Returns a hash of column objects for the table associated with this class.
db045db David Heinemeier Hansson Initial
dhh authored
751 def columns_hash
752 @columns_hash ||= columns.inject({}) { |hash, column| hash[column.name] = column; hash }
753 end
d0bd3b5 Jeremy Kemper Return PostgreSQL columns in the order they are declared #1374 (perlguy@...
jeremy authored
754
fed7d33 David Heinemeier Hansson Fixed documentation
dhh authored
755 # Returns an array of column names as strings.
49d0f0c David Heinemeier Hansson Speeded up eager loading a whole bunch
dhh authored
756 def column_names
d0bd3b5 Jeremy Kemper Return PostgreSQL columns in the order they are declared #1374 (perlguy@...
jeremy authored
757 @column_names ||= columns.map { |column| column.name }
49d0f0c David Heinemeier Hansson Speeded up eager loading a whole bunch
dhh authored
758 end
db045db David Heinemeier Hansson Initial
dhh authored
759
2948910 Misc doc fixes (typos/grammar/etc.). Closes #2430.
Marcel Molina authored
760 # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
761 # and columns used for single table inheritance have been removed.
db045db David Heinemeier Hansson Initial
dhh authored
762 def content_columns
c0899bc Add convenience predicate methods on Column class. In partial fullfilmen...
Marcel Molina authored
763 @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
db045db David Heinemeier Hansson Initial
dhh authored
764 end
765
766 # 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
767 # 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
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
768 # is available.
fed7d33 David Heinemeier Hansson Fixed documentation
dhh authored
769 def column_methods_hash #:nodoc:
d0bd3b5 Jeremy Kemper Return PostgreSQL columns in the order they are declared #1374 (perlguy@...
jeremy authored
770 @dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr|
3ab3a70 Jeremy Kemper Clarify semantics of ActiveRecord::Base#respond_to? Closes #2560.
jeremy authored
771 attr_name = attr.to_s
772 methods[attr.to_sym] = attr_name
773 methods["#{attr}=".to_sym] = attr_name
774 methods["#{attr}?".to_sym] = attr_name
775 methods["#{attr}_before_type_cast".to_sym] = attr_name
db045db David Heinemeier Hansson Initial
dhh authored
776 methods
777 end
778 end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
779
a293278 Pratik Merge docrails
lifo authored
780 # Resets all the cached information about columns, which will cause them
781 # to be reloaded on the next request.
782 #
783 # The most common usage pattern for this method is probably in a migration,
784 # when just after creating a table you want to populate it with some default
785 # values, eg:
786 #
787 # class CreateJobLevels < ActiveRecord::Migration
788 # def self.up
789 # create_table :job_levels do |t|
790 # t.integer :id
791 # t.string :name
792 #
793 # t.timestamps
794 # end
795 #
796 # JobLevel.reset_column_information
797 # %w{assistant executive manager director}.each do |type|
798 # JobLevel.create(:name => type)
799 # end
800 # end
801 #
802 # def self.down
803 # drop_table :job_levels
804 # end
805 # end
1314f48 David Heinemeier Hansson Added methods for resetting the cached information on classes that you w...
dhh authored
806 def reset_column_information
e129c56 Joshua Peek Wrap up attribute method reset concerns in 'undefine_attribute_methods'
josh authored
807 undefine_attribute_methods
d2c4b3b Pratik Rename Model.engine to active_relation_engine. Cache arel_table and the ...
lifo authored
808 @column_names = @columns = @columns_hash = @content_columns = @dynamic_methods_hash = @inheritance_column = nil
6e3bee6 Pratik Cache Model.arel_table
lifo authored
809 @arel_engine = @unscoped = @arel_table = nil
1314f48 David Heinemeier Hansson Added methods for resetting the cached information on classes that you w...
dhh authored
810 end
811
4eab375 David Heinemeier Hansson Finished polishing API docs
dhh authored
812 def reset_column_information_and_inheritable_attributes_for_all_subclasses#:nodoc:
1314f48 David Heinemeier Hansson Added methods for resetting the cached information on classes that you w...
dhh authored
813 subclasses.each { |klass| klass.reset_inheritable_attributes; klass.reset_column_information }
814 end
db045db David Heinemeier Hansson Initial
dhh authored
815
ce48b31 Santiago Pastorino Makes validates_acceptance_of to not override database fields [#4460 sta...
spastorino authored
816 def attribute_method?(attribute)
209ab7e José Valim Fix failing test.
josevalim authored
817 super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
ce48b31 Santiago Pastorino Makes validates_acceptance_of to not override database fields [#4460 sta...
spastorino authored
818 end
819
e714b49 José Valim Move validator, human_name and human_attribute_name to ActiveModel, remo...
josevalim authored
820 # Set the lookup ancestors for ActiveModel.
821 def lookup_ancestors #:nodoc:
ffeab4e Cleaned up ActiveRecord i18n scoping
Iain Hecker authored
822 klass = self
823 classes = [klass]
0905396 Emilio Tagua construct_finder_sql now use Arel
miloops authored
824 while klass != klass.base_class
ffeab4e Cleaned up ActiveRecord i18n scoping
Iain Hecker authored
825 classes << klass = klass.superclass
826 end
827 classes
828 rescue
829 # OPTIMIZE this rescue is to fix this test: ./test/cases/reflection_test.rb:56:in `test_human_name_for_column'
e033b5d Pratik Merge docrails
lifo authored
830 # Apparently the method base_class causes some trouble.
ffeab4e Cleaned up ActiveRecord i18n scoping
Iain Hecker authored
831 # It now works for sure.
832 [self]
833 end
834
e714b49 José Valim Move validator, human_name and human_attribute_name to ActiveModel, remo...
josevalim authored
835 # Set the i18n scope to overwrite ActiveModel.
836 def i18n_scope #:nodoc:
837 :activerecord
db045db David Heinemeier Hansson Initial
dhh authored
838 end
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
839
06afb8c Jeremy Kemper Subclasses of an abstract class work with single-table inheritance. Refe...
jeremy authored
840 # True if this isn't a concrete subclass needing a STI type condition.
841 def descends_from_active_record?
842 if superclass.abstract_class?
843 superclass.descends_from_active_record?
844 else
845 superclass == Base || !columns_hash.include?(inheritance_column)
846 end
db045db David Heinemeier Hansson Initial
dhh authored
847 end
848
b4ec990 Michael Koziarski Cache the descends_from_activerecord? call to speed up query generation....
NZKoz authored
849 def finder_needs_type_condition? #:nodoc:
850 # This is like this because benchmarking justifies the strange :false stuff
851 :true == (@finder_needs_type_condition ||= descends_from_active_record? ? :false : :true)
852 end
853
d0360a4 Jeremy Kemper Base.inspect handles Base itself and abstract_class? Don't use #<Foo .....
jeremy authored
854 # Returns a string like 'Post id:integer, title:string, body:text'
52a9e50 David Heinemeier Hansson Added ActiveRecord::Base.inspect to return a column-view like #<Post id:...
dhh authored
855 def inspect
d0360a4 Jeremy Kemper Base.inspect handles Base itself and abstract_class? Don't use #<Foo .....
jeremy authored
856 if self == Base
857 super
858 elsif abstract_class?
859 "#{super}(abstract)"
bb94ce9 Michael Koziarski Let inspect on AR classes work when the table doesn't exist. Closes #919...
NZKoz authored
860 elsif table_exists?
d0360a4 Jeremy Kemper Base.inspect handles Base itself and abstract_class? Don't use #<Foo .....
jeremy authored
861 attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
862 "#{super}(#{attr_list})"
bb94ce9 Michael Koziarski Let inspect on AR classes work when the table doesn't exist. Closes #919...
NZKoz authored
863 else
864 "#{super}(Table doesn't exist)"
d0360a4 Jeremy Kemper Base.inspect handles Base itself and abstract_class? Don't use #<Foo .....
jeremy authored
865 end
52a9e50 David Heinemeier Hansson Added ActiveRecord::Base.inspect to return a column-view like #<Post id:...
dhh authored
866 end
867
b445ab9 Michael Koziarski Rename quote to quote_value so the name can be used in AR models. #3628 ...
NZKoz authored
868 def quote_value(value, column = nil) #:nodoc:
b2c0ddf Add support for FrontBase (http://www.frontbase.com/) with a new adapter...
Marcel Molina authored
869 connection.quote(value,column)
4940383 David Heinemeier Hansson Fixed value quoting in all generated SQL statements, so that integers ar...
dhh authored
870 end
871
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
872 # Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to <tt>connection.quote</tt>.
4eab375 David Heinemeier Hansson Finished polishing API docs
dhh authored
873 def sanitize(object) #:nodoc:
4940383 David Heinemeier Hansson Fixed value quoting in all generated SQL statements, so that integers ar...
dhh authored
874 connection.quote(object)
db045db David Heinemeier Hansson Initial
dhh authored
875 end
876
97849de David Heinemeier Hansson Fixed that association proxies would fail === tests like PremiumSubscrip...
dhh authored
877 # Overwrite the default class equality method to provide support for association proxies.
878 def ===(object)
879 object.is_a?(self)
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
880 end
b840e4e Deprecated ActiveRecord::Base.threaded_connection in favor of ActiveReco...
Marcel Molina authored
881
d2f4750 Jamis Buck Add AR::Base.base_class for querying the ancestor AR::Base subclass [Jam...
jamis authored
882 # Returns the base AR subclass that this class descends from. If A
883 # extends AR::Base, A.base_class will return A. If B descends from A
884 # through some arbitrarily deep hierarchy, B.base_class will return A.
885 def base_class
886 class_of_active_record_descendant(self)
887 end
888
98dc582 Pratik Merge docrails.
lifo authored
889 # Set this to true if this is an abstract class (see <tt>abstract_class?</tt>).
def7460 risk danger olson Added Base.abstract_class? that marks which classes are not part of the ...
technoweenie authored
890 attr_accessor :abstract_class
891
892 # Returns whether this class is a base AR class. If A is a base class and
893 # B descends from A, then B.base_class will return B.
894 def abstract_class?
8b5f4e4 Jeremy Kemper Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized inst...
jeremy authored
895 defined?(@abstract_class) && @abstract_class == true
def7460 risk danger olson Added Base.abstract_class? that marks which classes are not part of the ...
technoweenie authored
896 end
897
4f39382 Pratik Ensure that respond_to? considers dynamic finder methods. Closes #11538....
lifo authored
898 def respond_to?(method_id, include_private = false)
143f5fb Josh Susser refactor dynamic finder name matching into its own class
joshsusser authored
899 if match = DynamicFinderMatch.match(method_id)
900 return true if all_attributes_exists?(match.attribute_names)
66ee589 Yaroslav Markin Introduce dynamic scopes for ActiveRecord: you can now use class methods...
yaroslav authored
901 elsif match = DynamicScopeMatch.match(method_id)
902 return true if all_attributes_exists?(match.attribute_names)
4f39382 Pratik Ensure that respond_to? considers dynamic finder methods. Closes #11538....
lifo authored
903 end
c3aa2bc Manfred Stienstra Ensure nested with_scope merges conditions inside out [#2193 state:resol...
Manfred authored
904
4f39382 Pratik Ensure that respond_to? considers dynamic finder methods. Closes #11538....
lifo authored
905 super
906 end
907
72483c0 risk danger olson Add ActiveRecord::Base.sti_name that checks ActiveRecord::Base#store_ful...
technoweenie authored
908 def sti_name
909 store_full_sti_class ? name : name.demodulize
910 end
911
cd90dcb Pratik Rename Model.active_relation to Model.unscoped
lifo authored
912 def unscoped
913 @unscoped ||= Relation.new(self, arel_table)
914 finder_needs_type_condition? ? @unscoped.where(type_condition) : @unscoped
f4a2356 Emilio Tagua Added ActiveRecord::Base#(where|join|project|group|order|take|skip) meth...
miloops authored
915 end
916
6e3bee6 Pratik Cache Model.arel_table
lifo authored
917 def arel_table
918 @arel_table ||= Arel::Table.new(table_name, :engine => arel_engine)
d2c4b3b Pratik Rename Model.engine to active_relation_engine. Cache arel_table and the ...
lifo authored
919 end
920
5a52523 Pratik Rename active_relation_engine -> arel_engine and active_relation_table -...
lifo authored
921 def arel_engine
922 @arel_engine ||= begin
a115b5d Pratik Ensure using proper engine for Arel::Table
lifo authored
923 if self == ActiveRecord::Base
924 Arel::Table.engine
925 else
5a52523 Pratik Rename active_relation_engine -> arel_engine and active_relation_table -...
lifo authored
926 connection_handler.connection_pools[name] ? Arel::Sql::Engine.new(self) : superclass.arel_engine
a115b5d Pratik Ensure using proper engine for Arel::Table
lifo authored
927 end
928 end
77c23b2 Pratik Use PredicateBuilder for sql hash sanitization
lifo authored
929 end
930
db045db David Heinemeier Hansson Initial
dhh authored
931 private
4b4dd54 Jeremy Kemper Clashing type columns due to a sloppy join shouldn't wreck single-table ...
jeremy authored
932 # Finder methods must instantiate through this method to work with the
933 # single-table inheritance model that makes it possible to create
934 # objects of different types from the same table.
db045db David Heinemeier Hansson Initial
dhh authored
935 def instantiate(record)
3fc2d1e Jeremy Kemper Extract class-finder method from instantiate
jeremy authored
936 object = find_sti_class(record[inheritance_column]).allocate
605bc77 David Heinemeier Hansson Added a better exception for when a type column is used in a table witho...
dhh authored
937
6d30002 Pratik Revert "Refactoring attributes/types" [#3348 state:open]
lifo authored
938 object.instance_variable_set(:'@attributes', record)
3fc2d1e Jeremy Kemper Extract class-finder method from instantiate
jeremy authored
939 object.instance_variable_set(:'@attributes_cache', {})
115230e Aaron Patterson cleaning up some test warnings
tenderlove authored
940 object.instance_variable_set(:@new_record, false)
5de3698 Aaron Patterson cleaning up many more warnings in activerecord [#4180 state:resolved]
tenderlove authored
941 object.instance_variable_set(:@readonly, false)
942 object.instance_variable_set(:@destroyed, false)
943 object.instance_variable_set(:@marked_for_destruction, false)
8c3e46c Aaron Patterson clean up more warnings, remove unnecessary methods, fix eval line number...
tenderlove authored
944 object.instance_variable_set(:@previously_changed, {})
945 object.instance_variable_set(:@changed_attributes, {})
55efae2 Jeremy Kemper Performance: absorb instantiate and initialize_with_callbacks into the B...
jeremy authored
946
4f37b97 José Valim Changed ActiveRecord to use new callbacks and speed up observers by only...
josevalim authored
947 object.send(:_run_find_callbacks)
948 object.send(:_run_initialize_callbacks)
55efae2 Jeremy Kemper Performance: absorb instantiate and initialize_with_callbacks into the B...
jeremy authored
949
81737fc Jeremy Kemper r1613@asus: jeremy | 2005-07-03 07:04:53 -0700
jeremy authored
950 object
db045db David Heinemeier Hansson Initial
dhh authored
951 end
81737fc Jeremy Kemper r1613@asus: jeremy | 2005-07-03 07:04:53 -0700
jeremy authored
952
3fc2d1e Jeremy Kemper Extract class-finder method from instantiate
jeremy authored
953 def find_sti_class(type_name)
954 if type_name.blank? || !columns_hash.include?(inheritance_column)
955 self
956 else
957 begin
958 compute_type(type_name)
959 rescue NameError
960 raise SubclassNotFound,
961 "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " +
962 "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
963 "Please rename this column if you didn't intend it to be used for storing the inheritance class " +
964 "or overwrite #{name}.inheritance_column to use another column for that information."
965 end
966 end
967 end
968
bed9179 Pratik Make scopes use relations under the hood
lifo authored
969 def construct_finder_arel(options = {}, scope = nil)
8ff2fb6 Pratik Make default_scope work with Relations
lifo authored
970 relation = options.is_a?(Hash) ? unscoped.apply_finder_options(options) : unscoped.merge(options)
bed9179 Pratik Make scopes use relations under the hood
lifo authored
971 relation = scope.merge(relation) if scope
6b67df7 Emilio Tagua Revert "Revert "Add readonly support for relations.""
miloops authored
972 relation
19d2ff8 Emilio Tagua Calculations now use Arel to construct the query.
miloops authored
973 end
974
2d0bc08 Pratik Make type_condition return Arel predicate and not a string condition
lifo authored
975 def type_condition
5a52523 Pratik Rename active_relation_engine -> arel_engine and active_relation_table -...
lifo authored
976 sti_column = arel_table[inheritance_column]
d200d08 Pratik Use arel for building the STI type condition
lifo authored
977 condition = sti_column.eq(sti_name)
978 subclasses.each{|subclass| condition = condition.or(sti_column.eq(subclass.sti_name)) }
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
979
2d0bc08 Pratik Make type_condition return Arel predicate and not a string condition
lifo authored
980 condition
db045db David Heinemeier Hansson Initial
dhh authored
981 end
982
983 # Guesses the table name, but does not decorate it with prefix and suffix information.
def7460 risk danger olson Added Base.abstract_class? that marks which classes are not part of the ...
technoweenie authored
984 def undecorated_table_name(class_name = base_class.name)
3b0e1d9 Joshua Peek Prefer string core_ext inflector methods over directly accessing Inflect...
josh authored
985 table_name = class_name.to_s.demodulize.underscore
986 table_name = table_name.pluralize if pluralize_table_names
6e39c9e Jeremy Kemper r1614@asus: jeremy | 2005-07-03 08:01:08 -0700
jeremy authored
987 table_name
db045db David Heinemeier Hansson Initial
dhh authored
988 end
989
4a8c880 Xavier Noria refactors AR::Base#reset_table_name
fxn authored
990 # Computes and returns a table name according to default conventions.
991 def compute_table_name
992 base = base_class
993 if self == base
994 # Nested classes are prefixed with singular parent table name.
995 if parent < ActiveRecord::Base && !parent.abstract_class?
996 contained = parent.table_name
997 contained = contained.singularize if parent.pluralize_table_names
998 contained << '_'
999 end
1000 "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{table_name_suffix}"
1001 else
1002 # STI subclasses always use their superclass' table.
1003 base.table_name
1004 end
1005 end
1006
39e1ac6 Pratik Merge docrails
lifo authored
1007 # Enables dynamic finders like <tt>find_by_user_name(user_name)</tt> and <tt>find_by_user_name_and_password(user_name, password)</tt>
1efc8ed Pratik Fix dynamic finder docs
lifo authored
1008 # that are turned into <tt>where(:user_name => user_name).first</tt> and <tt>where(:user_name => user_name, :password => :password).first</tt>
1009 # respectively. Also works for <tt>all</tt> by using <tt>find_all_by_amount(50)</tt> that is turned into <tt>where(:amount => 50).all</tt>.
2a30594 risk danger olson documentation project patches, closes #7342, #7319, #7316, #7190 [jeremy...
technoweenie authored
1010 #
39e1ac6 Pratik Merge docrails
lifo authored
1011 # It's even possible to use all the additional parameters to +find+. For example, the full interface for +find_all_by_amount+
1012 # is actually <tt>find_all_by_amount(amount, options)</tt>.
4a1388a Define dynamic finders as real methods after first usage. Close #9317
Tobias Lütke authored
1013 #
66ee589 Yaroslav Markin Introduce dynamic scopes for ActiveRecord: you can now use class methods...
yaroslav authored
1014 # Each dynamic finder, scope or initializer/creator is also defined in the class after it is first invoked, so that future
4a1388a Define dynamic finders as real methods after first usage. Close #9317
Tobias Lütke authored
1015 # attempts to use it do not run through method_missing.
8a77c4a Fixed issue where block is not called on the very first invocation of a ...
Ken Miller authored
1016 def method_missing(method_id, *arguments, &block)
143f5fb Josh Susser refactor dynamic finder name matching into its own class
joshsusser authored
1017 if match = DynamicFinderMatch.match(method_id)
1018 attribute_names = match.attribute_names
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
1019 super unless all_attributes_exists?(attribute_names)
143f5fb Josh Susser refactor dynamic finder name matching into its own class
joshsusser authored
1020 if match.finder?
8829d6e Pratik Make Model.find_by_* and Model.find_all_by_* use relations and remove dy...
lifo authored
1021 options = arguments.extract_options!
bed9179 Pratik Make scopes use relations under the hood
lifo authored
1022 relation = options.any? ? construct_finder_arel(options, current_scoped_methods) : scoped
8829d6e Pratik Make Model.find_by_* and Model.find_all_by_* use relations and remove dy...
lifo authored
1023 relation.send :find_by_attributes, match, attribute_names, *arguments
143f5fb Josh Susser refactor dynamic finder name matching into its own class
joshsusser authored
1024 elsif match.instantiator?
85770ec Pratik Make Model.find_or_create_by_* and find_or_initialize_by_* use relations...
lifo authored
1025 scoped.send :find_or_instantiator_by_attributes, match, attribute_names, *arguments, &block
143f5fb Josh Susser refactor dynamic finder name matching into its own class
joshsusser authored
1026 end
66ee589 Yaroslav Markin Introduce dynamic scopes for ActiveRecord: you can now use class methods...
yaroslav authored
1027 elsif match = DynamicScopeMatch.match(method_id)
1028 attribute_names = match.attribute_names
1029 super unless all_attributes_exists?(attribute_names)
1030 if match.scope?
13e00ce Santiago Pastorino fix stack trace lines on class_eval
spastorino authored
1031 self.class_eval <<-METHOD, __FILE__, __LINE__ + 1
66ee589 Yaroslav Markin Introduce dynamic scopes for ActiveRecord: you can now use class methods...
yaroslav authored
1032 def self.#{method_id}(*args) # def self.scoped_by_user_name_and_password(*args)
1033 options = args.extract_options! # options = args.extract_options!
1034 attributes = construct_attributes_from_arguments( # attributes = construct_attributes_from_arguments(
1035 [:#{attribute_names.join(',:')}], args # [:user_name, :password], args
1036 ) # )
0905396 Emilio Tagua construct_finder_sql now use Arel
miloops authored
1037 #
66ee589 Yaroslav Markin Introduce dynamic scopes for ActiveRecord: you can now use class methods...
yaroslav authored
1038 scoped(:conditions => attributes) # scoped(:conditions => attributes)
1039 end # end
13e00ce Santiago Pastorino fix stack trace lines on class_eval
spastorino authored
1040 METHOD
66ee589 Yaroslav Markin Introduce dynamic scopes for ActiveRecord: you can now use class methods...
yaroslav authored
1041 send(method_id, *arguments)
1042 end
ac8fd7d David Heinemeier Hansson Added dynamic attribute-based finders as a cleaner way of getting object...
dhh authored
1043 else
1044 super
1045 end
1046 end
db045db David Heinemeier Hansson Initial
dhh authored
1047
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
1048 def construct_attributes_from_arguments(attribute_names, arguments)
1049 attributes = {}
1050 attribute_names.each_with_index { |name, idx| attributes[name] = arguments[idx] }
1051 attributes
1052 end
1053
abdf546 Jeremy Kemper Support aggregations in finder conditions. Closes #10572.
jeremy authored
1054 # Similar in purpose to +expand_hash_conditions_for_aggregates+.
1055 def expand_attribute_names_for_aggregates(attribute_names)
1056 expanded_attribute_names = []
1057 attribute_names.each do |attribute_name|
1058 unless (aggregation = reflect_on_aggregation(attribute_name.to_sym)).nil?
1059 aggregate_mapping(aggregation).each do |field_attr, aggregate_attr|
1060 expanded_attribute_names << field_attr
1061 end
1062 else
1063 expanded_attribute_names << attribute_name
1064 end
1065 end
1066 expanded_attribute_names
1067 end
1068
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
1069 def all_attributes_exists?(attribute_names)
abdf546 Jeremy Kemper Support aggregations in finder conditions. Closes #10572.
jeremy authored
1070 attribute_names = expand_attribute_names_for_aggregates(attribute_names)
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
1071 attribute_names.all? { |name| column_methods_hash.include?(name.to_sym) }
7367325 Jeremy Kemper Document Active Record exceptions. Closes #10444.
jeremy authored
1072 end
a5a82d9 David Heinemeier Hansson Added extension capabilities to has_many and has_and_belongs_to_many pro...
dhh authored
1073
db045db David Heinemeier Hansson Initial
dhh authored
1074 protected
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1075 # Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash.
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
1076 # method_name may be <tt>:find</tt> or <tt>:create</tt>. <tt>:find</tt> parameter is <tt>Relation</tt> while
1077 # <tt>:create</tt> parameters are an attributes hash.
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1078 #
1079 # class Article < ActiveRecord::Base
1080 # def self.create_with_scope
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
1081 # with_scope(:find => where(:blog_id => 1), :create => { :blog_id => 1 }) do
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1082 # find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1
1083 # a = create(1)
1084 # a.blog_id # => 1
1085 # end
1086 # end
1087 # end
1088 #
b0391d1 David Heinemeier Hansson Docfix (closes #8674)
dhh authored
1089 # In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
1090 # <tt>where</tt>, <tt>includes</tt>, and <tt>joins</tt> operations in <tt>Relation</tt>, which are merged.
39e1ac6 Pratik Merge docrails
lifo authored
1091 #
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
1092 # <tt>joins</tt> operations are uniqued so multiple scopes can join in the same table without table aliasing
39e1ac6 Pratik Merge docrails
lifo authored
1093 # problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the
1094 # array of strings format for your joins.
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1095 #
1096 # class Article < ActiveRecord::Base
1097 # def self.find_with_scope
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
1098 # with_scope(:find => where(:blog_id => 1).limit(1), :create => { :blog_id => 1 }) do
1099 # with_scope(:find => limit(10)) do
1100 # all # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1101 # end
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
1102 # with_scope(:find => where(:author_id => 3)) do
1103 # all # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1104 # end
1105 # end
1106 # end
1107 # end
1108 #
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
1109 # You can ignore any previous scopings by using the <tt>with_exclusive_scope</tt> method.
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1110 #
1111 # class Article < ActiveRecord::Base
1112 # def self.find_with_exclusive_scope
2c27e3d Pratik Some doc updates reflecting the new query API
lifo authored
1113 # with_scope(:find => where(:blog_id => 1).limit(1)) do
1114 # with_exclusive_scope(:find => limit(10))
1115 # all # => SELECT * from articles LIMIT 10
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1116 # end
1117 # end
1118 # end
1119 # end
a293278 Pratik Merge docrails
lifo authored
1120 #
1121 # *Note*: the +:find+ scope also has effect on update and deletion methods,
1122 # like +update_all+ and +delete_all+.
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1123 def with_scope(method_scoping = {}, action = :merge, &block)
1124 method_scoping = method_scoping.method_scoping if method_scoping.respond_to?(:method_scoping)
1125
bed9179 Pratik Make scopes use relations under the hood
lifo authored
1126 if method_scoping.is_a?(Hash)
1127 # Dup first and second level of hash (method and params).
1128 method_scoping = method_scoping.inject({}) do |hash, (method, params)|
1129 hash[method] = (params == true) ? params : params.dup
1130 hash
1131 end
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1132
bed9179 Pratik Make scopes use relations under the hood
lifo authored
1133 method_scoping.assert_valid_keys([ :find, :create ])
1134 relation = construct_finder_arel(method_scoping[:find] || {})
1135
1136 if current_scoped_methods && current_scoped_methods.create_with_value && method_scoping[:create]
1b78a3f Pratik with_scope no longer needs :reverse_merge
lifo authored
1137 scope_for_create = if action == :merge
bed9179 Pratik Make scopes use relations under the hood
lifo authored
1138 current_scoped_methods.create_with_value.merge(method_scoping[:create])
1139 else
1140 method_scoping[:create]
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1141 end
bed9179 Pratik Make scopes use relations under the hood
lifo authored
1142
1143 relation = relation.create_with(scope_for_create)
1144 else
1145 scope_for_create = method_scoping[:create]
1146 scope_for_create ||= current_scoped_methods.create_with_value if current_scoped_methods
1147 relation = relation.create_with(scope_for_create) if scope_for_create
1148 end
1149
1150 method_scoping = relation
1151 end
1152
1b78a3f Pratik with_scope no longer needs :reverse_merge
lifo authored
1153 method_scoping = current_scoped_methods.merge(method_scoping) if current_scoped_methods && action == :merge
1edd21b Jeremy Kemper with_scope is protected. Closes #8524.
jeremy authored
1154
1155 self.scoped_methods << method_scoping
1156 begin
1157 yield
1158 ensure
1159 self.scoped_methods.pop
1160 end
1161 end
1162
1163 # Works like with_scope, but discards any nested properties.
1164 def with_exclusive_scope(method_scoping = {}, &block)
1165 with_scope(method_scoping, :overwrite, &block)
1166 end
1167
0e27463 Xavier Noria removes unnecessary assignment and local variable in AR::Base#subclasses...
fxn authored
1168 # Returns a list of all subclasses of this class, meaning all descendants.
f8eddcc make ActiveRecord::Base.subclasses a public method
Emmanuel Oga authored
1169 def subclasses
db045db David Heinemeier Hansson Initial
dhh authored