|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1 |
module ActiveRecord |
|
fed7d334
»
|
dhh |
2006-03-27 |
Fixed documentation |
2 |
class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc: |
|
291adbd3
»
|
technoweenie |
2006-07-19 |
fix association exception m... |
3 |
def initialize(owner_class_name, reflection) |
| |
4 |
super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class_name}") |
|
57af961a
»
|
technoweenie |
2006-03-18 |
Raise error when trying to ... |
5 |
end |
| |
6 |
end |
| |
7 |
|
|
fed7d334
»
|
dhh |
2006-03-27 |
Fixed documentation |
8 |
class HasManyThroughAssociationPolymorphicError < ActiveRecordError #:nodoc: |
|
57af961a
»
|
technoweenie |
2006-03-18 |
Raise error when trying to ... |
9 |
def initialize(owner_class_name, reflection, source_reflection) |
|
291adbd3
»
|
technoweenie |
2006-07-19 |
fix association exception m... |
10 |
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}'.") |
|
57af961a
»
|
technoweenie |
2006-03-18 |
Raise error when trying to ... |
11 |
end |
| |
12 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
13 |
|
|
e3dab67c
»
|
technoweenie |
2007-03-12 |
Allow a polymorphic :source... |
14 |
class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc: |
| |
15 |
def initialize(owner_class_name, reflection, source_reflection) |
| |
16 |
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.") |
| |
17 |
end |
| |
18 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
19 |
|
|
fed7d334
»
|
dhh |
2006-03-27 |
Fixed documentation |
20 |
class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc: |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
21 |
def initialize(reflection) |
|
291adbd3
»
|
technoweenie |
2006-07-19 |
fix association exception m... |
22 |
through_reflection = reflection.through_reflection |
| |
23 |
source_reflection_names = reflection.source_reflection_names |
| |
24 |
source_associations = reflection.through_reflection.klass.reflect_on_all_associations.collect { |a| a.name.inspect } |
|
6de83562
»
|
dhh |
2009-02-27 |
Force all internal calls to... |
25 |
super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?") |
|
57af961a
»
|
technoweenie |
2006-03-18 |
Raise error when trying to ... |
26 |
end |
| |
27 |
end |
| |
28 |
|
|
0aa0c84c
»
|
dhh |
2007-01-26 |
Nodoc the irrelevant (from ... |
29 |
class HasManyThroughSourceAssociationMacroError < ActiveRecordError #:nodoc: |
|
4d232025
»
|
technoweenie |
2006-04-05 |
Added descriptive error mes... |
30 |
def initialize(reflection) |
|
291adbd3
»
|
technoweenie |
2006-07-19 |
fix association exception m... |
31 |
through_reflection = reflection.through_reflection |
| |
32 |
source_reflection = reflection.source_reflection |
| |
33 |
super("Invalid source reflection macro :#{source_reflection.macro}#{" :through" if source_reflection.options[:through]} for has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}. Use :source to specify the source reflection.") |
|
4d232025
»
|
technoweenie |
2006-04-05 |
Added descriptive error mes... |
34 |
end |
| |
35 |
end |
| |
36 |
|
|
f6b12c11
»
|
lifo |
2008-04-05 |
Refactor HasManyThroughAsso... |
37 |
class HasManyThroughCantAssociateThroughHasManyReflection < ActiveRecordError #:nodoc: |
| |
38 |
def initialize(owner, reflection) |
| |
39 |
super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.") |
| |
40 |
end |
| |
41 |
end |
|
0da426be
»
|
jeremy |
2006-08-18 |
Add records to has_many :th... |
42 |
class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc: |
| |
43 |
def initialize(owner, reflection) |
| |
44 |
super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.") |
| |
45 |
end |
| |
46 |
end |
| |
47 |
|
|
4b639904
»
|
jeremy |
2007-10-27 |
Fix has_many :through delet... |
48 |
class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc: |
| |
49 |
def initialize(owner, reflection) |
| |
50 |
super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.") |
| |
51 |
end |
| |
52 |
end |
| |
53 |
|
|
fed7d334
»
|
dhh |
2006-03-27 |
Fixed documentation |
54 |
class EagerLoadPolymorphicError < ActiveRecordError #:nodoc: |
|
57af961a
»
|
technoweenie |
2006-03-18 |
Raise error when trying to ... |
55 |
def initialize(reflection) |
|
291adbd3
»
|
technoweenie |
2006-07-19 |
fix association exception m... |
56 |
super("Can not eagerly load the polymorphic association #{reflection.name.inspect}") |
|
57af961a
»
|
technoweenie |
2006-03-18 |
Raise error when trying to ... |
57 |
end |
| |
58 |
end |
| |
59 |
|
|
c61b10b6
»
|
technoweenie |
2006-04-24 |
Raise error when trying to ... |
60 |
class ReadOnlyAssociation < ActiveRecordError #:nodoc: |
| |
61 |
def initialize(reflection) |
|
291adbd3
»
|
technoweenie |
2006-07-19 |
fix association exception m... |
62 |
super("Can not add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.") |
|
c61b10b6
»
|
technoweenie |
2006-04-24 |
Raise error when trying to ... |
63 |
end |
| |
64 |
end |
| |
65 |
|
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
66 |
# See ActiveRecord::Associations::ClassMethods for documentation. |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
67 |
module Associations # :nodoc: |
|
7254d237
»
|
josh |
2008-11-24 |
Autoload ActiveRecord files |
68 |
# These classes will be loaded when associatoins are created. |
| |
69 |
# So there is no need to eager load them. |
| |
70 |
autoload :AssociationCollection, 'active_record/associations/association_collection' |
| |
71 |
autoload :AssociationProxy, 'active_record/associations/association_proxy' |
| |
72 |
autoload :BelongsToAssociation, 'active_record/associations/belongs_to_association' |
| |
73 |
autoload :BelongsToPolymorphicAssociation, 'active_record/associations/belongs_to_polymorphic_association' |
| |
74 |
autoload :HasAndBelongsToManyAssociation, 'active_record/associations/has_and_belongs_to_many_association' |
| |
75 |
autoload :HasManyAssociation, 'active_record/associations/has_many_association' |
| |
76 |
autoload :HasManyThroughAssociation, 'active_record/associations/has_many_through_association' |
| |
77 |
autoload :HasOneAssociation, 'active_record/associations/has_one_association' |
| |
78 |
autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association' |
| |
79 |
|
|
61864909
»
|
Marcel Molina |
2006-04-29 |
Replace Ruby's deprecated a... |
80 |
def self.included(base) |
|
7c8d2f28
»
|
dhh |
2005-04-02 |
Removed broken attempt to D... |
81 |
base.extend(ClassMethods) |
| |
82 |
end |
| |
83 |
|
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
84 |
# Clears out the association cache |
|
4b229d10
»
|
dhh |
2004-12-22 |
Added Base#clear_associatio... |
85 |
def clear_association_cache #:nodoc: |
| |
86 |
self.class.reflect_on_all_associations.to_a.each do |assoc| |
| |
87 |
instance_variable_set "@#{assoc.name}", nil |
|
85fbb22f
»
|
dhh |
2006-09-05 |
Backed out of new_record? t... |
88 |
end unless self.new_record? |
|
4b229d10
»
|
dhh |
2004-12-22 |
Added Base#clear_associatio... |
89 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
90 |
|
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
91 |
private |
| |
92 |
# Gets the specified association instance if it responds to :loaded?, nil otherwise. |
| |
93 |
def association_instance_get(name) |
| |
94 |
association = instance_variable_get("@#{name}") |
| |
95 |
association if association.respond_to?(:loaded?) |
| |
96 |
end |
| |
97 |
|
| |
98 |
# Set the specified association instance. |
| |
99 |
def association_instance_set(name, association) |
| |
100 |
instance_variable_set("@#{name}", association) |
| |
101 |
end |
| |
102 |
|
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
103 |
# Associations are a set of macro-like class methods for tying objects together through foreign keys. They express relationships like |
| |
104 |
# "Project has one Project Manager" or "Project belongs to a Portfolio". Each macro adds a number of methods to the class which are |
| |
105 |
# specialized according to the collection or association symbol and the options hash. It works much the same way as Ruby's own <tt>attr*</tt> |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
106 |
# methods. Example: |
| |
107 |
# |
| |
108 |
# class Project < ActiveRecord::Base |
| |
109 |
# belongs_to :portfolio |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
110 |
# has_one :project_manager |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
111 |
# has_many :milestones |
| |
112 |
# has_and_belongs_to_many :categories |
| |
113 |
# end |
| |
114 |
# |
| |
115 |
# The project class now has the following methods (and more) to ease the traversal and manipulation of its relationships: |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
116 |
# * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt> |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
117 |
# * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt> |
| |
118 |
# * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt> |
|
7aa9eed8
»
|
jeremy |
2006-09-01 |
Deprecation: update docs. C... |
119 |
# <tt>Project#milestones.delete(milestone), Project#milestones.find(milestone_id), Project#milestones.find(:all, options),</tt> |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
120 |
# <tt>Project#milestones.build, Project#milestones.create</tt> |
| |
121 |
# * <tt>Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1),</tt> |
| |
122 |
# <tt>Project#categories.delete(category1)</tt> |
| |
123 |
# |
|
7288fd3e
»
|
jeremy |
2007-05-18 |
Docs: warn that association... |
124 |
# === A word of warning |
| |
125 |
# |
| |
126 |
# Don't create associations that have the same name as instance methods of ActiveRecord::Base. Since the association |
| |
127 |
# adds a method with that name to its model, it will override the inherited method and break things. |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
128 |
# For instance, +attributes+ and +connection+ would be bad choices for association names. |
|
7288fd3e
»
|
jeremy |
2007-05-18 |
Docs: warn that association... |
129 |
# |
|
ff6d2aae
»
|
jeremy |
2007-05-30 |
Quickref for association me... |
130 |
# == Auto-generated methods |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
131 |
# |
|
c23c9bd1
»
|
technoweenie |
2008-03-21 |
Allow association scoping f... |
132 |
# === Singular associations (one-to-one) |
|
ff6d2aae
»
|
jeremy |
2007-05-30 |
Quickref for association me... |
133 |
# | | belongs_to | |
| |
134 |
# generated methods | belongs_to | :polymorphic | has_one |
| |
135 |
# ----------------------------------+------------+--------------+--------- |
|
53cd102b
»
|
lifo |
2009-02-24 |
Merge with docrails |
136 |
# other | X | X | X |
| |
137 |
# other=(other) | X | X | X |
| |
138 |
# build_other(attributes={}) | X | | X |
| |
139 |
# create_other(attributes={}) | X | | X |
| |
140 |
# other.create!(attributes={}) | | | X |
|
ff6d2aae
»
|
jeremy |
2007-05-30 |
Quickref for association me... |
141 |
# |
| |
142 |
# ===Collection associations (one-to-many / many-to-many) |
| |
143 |
# | | | has_many |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
144 |
# generated methods | habtm | has_many | :through |
|
ff6d2aae
»
|
jeremy |
2007-05-30 |
Quickref for association me... |
145 |
# ----------------------------------+-------+----------+---------- |
|
53cd102b
»
|
lifo |
2009-02-24 |
Merge with docrails |
146 |
# others | X | X | X |
| |
147 |
# others=(other,other,...) | X | X | X |
| |
148 |
# other_ids | X | X | X |
| |
149 |
# other_ids=(id,id,...) | X | X | X |
| |
150 |
# others<< | X | X | X |
| |
151 |
# others.push | X | X | X |
| |
152 |
# others.concat | X | X | X |
| |
153 |
# others.build(attributes={}) | X | X | X |
| |
154 |
# others.create(attributes={}) | X | X | X |
| |
155 |
# others.create!(attributes={}) | X | X | X |
| |
156 |
# others.size | X | X | X |
| |
157 |
# others.length | X | X | X |
| |
158 |
# others.count | X | X | X |
| |
159 |
# others.sum(args*,&block) | X | X | X |
| |
160 |
# others.empty? | X | X | X |
| |
161 |
# others.clear | X | X | X |
| |
162 |
# others.delete(other,other,...) | X | X | X |
| |
163 |
# others.delete_all | X | X | |
| |
164 |
# others.destroy_all | X | X | X |
| |
165 |
# others.find(*args) | X | X | X |
| |
166 |
# others.find_first | X | | |
| |
167 |
# others.exists? | X | X | X |
| |
168 |
# others.uniq | X | X | X |
| |
169 |
# others.reset | X | X | X |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
170 |
# |
|
51d840e2
»
|
NZKoz |
2007-01-14 |
Improve association documen... |
171 |
# == Cardinality and associations |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
172 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
173 |
# Active Record associations can be used to describe one-to-one, one-to-many and many-to-many |
|
aa4af60a
»
|
lifo |
2008-04-04 |
Improve documentation. |
174 |
# relationships between models. Each model uses an association to describe its role in |
| |
175 |
# the relation. The +belongs_to+ association is always used in the model that has |
|
8296c680
»
|
technoweenie |
2007-01-22 |
Remove useless code in #att... |
176 |
# the foreign key. |
|
51d840e2
»
|
NZKoz |
2007-01-14 |
Improve association documen... |
177 |
# |
| |
178 |
# === One-to-one |
| |
179 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
180 |
# Use +has_one+ in the base, and +belongs_to+ in the associated model. |
|
51d840e2
»
|
NZKoz |
2007-01-14 |
Improve association documen... |
181 |
# |
| |
182 |
# class Employee < ActiveRecord::Base |
| |
183 |
# has_one :office |
| |
184 |
# end |
| |
185 |
# class Office < ActiveRecord::Base |
| |
186 |
# belongs_to :employee # foreign key - employee_id |
| |
187 |
# end |
| |
188 |
# |
| |
189 |
# === One-to-many |
| |
190 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
191 |
# Use +has_many+ in the base, and +belongs_to+ in the associated model. |
|
51d840e2
»
|
NZKoz |
2007-01-14 |
Improve association documen... |
192 |
# |
| |
193 |
# class Manager < ActiveRecord::Base |
| |
194 |
# has_many :employees |
| |
195 |
# end |
| |
196 |
# class Employee < ActiveRecord::Base |
|
8296c680
»
|
technoweenie |
2007-01-22 |
Remove useless code in #att... |
197 |
# belongs_to :manager # foreign key - manager_id |
|
51d840e2
»
|
NZKoz |
2007-01-14 |
Improve association documen... |
198 |
# end |
| |
199 |
# |
| |
200 |
# === Many-to-many |
| |
201 |
# |
| |
202 |
# There are two ways to build a many-to-many relationship. |
| |
203 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
204 |
# The first way uses a +has_many+ association with the <tt>:through</tt> option and a join model, so |
|
51d840e2
»
|
NZKoz |
2007-01-14 |
Improve association documen... |
205 |
# there are two stages of associations. |
| |
206 |
# |
| |
207 |
# class Assignment < ActiveRecord::Base |
| |
208 |
# belongs_to :programmer # foreign key - programmer_id |
| |
209 |
# belongs_to :project # foreign key - project_id |
| |
210 |
# end |
| |
211 |
# class Programmer < ActiveRecord::Base |
| |
212 |
# has_many :assignments |
| |
213 |
# has_many :projects, :through => :assignments |
| |
214 |
# end |
| |
215 |
# class Project < ActiveRecord::Base |
| |
216 |
# has_many :assignments |
| |
217 |
# has_many :programmers, :through => :assignments |
| |
218 |
# end |
| |
219 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
220 |
# For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table |
|
51d840e2
»
|
NZKoz |
2007-01-14 |
Improve association documen... |
221 |
# that has no corresponding model or primary key. |
| |
222 |
# |
| |
223 |
# class Programmer < ActiveRecord::Base |
| |
224 |
# has_and_belongs_to_many :projects # foreign keys in the join table |
| |
225 |
# end |
| |
226 |
# class Project < ActiveRecord::Base |
| |
227 |
# has_and_belongs_to_many :programmers # foreign keys in the join table |
| |
228 |
# end |
| |
229 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
230 |
# Choosing which way to build a many-to-many relationship is not always simple. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
231 |
# If you need to work with the relationship model as its own entity, |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
232 |
# use <tt>has_many :through</tt>. Use +has_and_belongs_to_many+ when working with legacy schemas or when |
|
51d840e2
»
|
NZKoz |
2007-01-14 |
Improve association documen... |
233 |
# you never work directly with the relationship itself. |
| |
234 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
235 |
# == Is it a +belongs_to+ or +has_one+ association? |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
236 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
237 |
# Both express a 1-1 relationship. The difference is mostly where to place the foreign key, which goes on the table for the class |
| |
238 |
# declaring the +belongs_to+ relationship. Example: |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
239 |
# |
|
69d8ca4c
»
|
jeremy |
2006-07-07 |
Clearer has_one/belongs_to ... |
240 |
# class User < ActiveRecord::Base |
| |
241 |
# # I reference an account. |
| |
242 |
# belongs_to :account |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
243 |
# end |
| |
244 |
# |
|
69d8ca4c
»
|
jeremy |
2006-07-07 |
Clearer has_one/belongs_to ... |
245 |
# class Account < ActiveRecord::Base |
| |
246 |
# # One user references me. |
| |
247 |
# has_one :user |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
248 |
# end |
| |
249 |
# |
| |
250 |
# The tables for these classes could look something like: |
| |
251 |
# |
|
69d8ca4c
»
|
jeremy |
2006-07-07 |
Clearer has_one/belongs_to ... |
252 |
# CREATE TABLE users ( |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
253 |
# id int(11) NOT NULL auto_increment, |
|
69d8ca4c
»
|
jeremy |
2006-07-07 |
Clearer has_one/belongs_to ... |
254 |
# account_id int(11) default NULL, |
| |
255 |
# name varchar default NULL, |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
256 |
# PRIMARY KEY (id) |
| |
257 |
# ) |
| |
258 |
# |
|
69d8ca4c
»
|
jeremy |
2006-07-07 |
Clearer has_one/belongs_to ... |
259 |
# CREATE TABLE accounts ( |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
260 |
# id int(11) NOT NULL auto_increment, |
| |
261 |
# name varchar default NULL, |
| |
262 |
# PRIMARY KEY (id) |
| |
263 |
# ) |
| |
264 |
# |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
265 |
# == Unsaved objects and associations |
| |
266 |
# |
|
7143d801
»
|
Marcel Molina |
2007-11-07 |
Smattering of grammatical f... |
267 |
# You can manipulate objects and associations before they are saved to the database, but there is some special behavior you should be |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
268 |
# aware of, mostly involving the saving of associated objects. |
| |
269 |
# |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
270 |
# Unless you enable the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>, |
| |
271 |
# <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association, |
| |
272 |
# in which case the members are always saved. |
| |
273 |
# |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
274 |
# === One-to-one associations |
| |
275 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
276 |
# * Assigning an object to a +has_one+ association automatically saves that object and the object being replaced (if there is one), in |
| |
277 |
# order to update their primary keys - except if the parent object is unsaved (<tt>new_record? == true</tt>). |
| |
278 |
# * If either of these saves fail (due to one of the objects being invalid) the assignment statement returns +false+ and the assignment |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
279 |
# is cancelled. |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
280 |
# * If you wish to assign an object to a +has_one+ association without saving it, use the <tt>association.build</tt> method (documented below). |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
281 |
# * Assigning an object to a +belongs_to+ association does not save the object, since the foreign key field belongs on the parent. It |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
282 |
# does not save the parent either. |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
283 |
# |
| |
284 |
# === Collections |
| |
285 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
286 |
# * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically saves that object, except if the parent object |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
287 |
# (the owner of the collection) is not yet stored in the database. |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
288 |
# * If saving any of the objects being added to a collection (via <tt>push</tt> or similar) fails, then <tt>push</tt> returns +false+. |
| |
289 |
# * You can add an object to a collection without automatically saving it by using the <tt>collection.build</tt> method (documented below). |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
290 |
# * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically saved when the parent is saved. |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
291 |
# |
|
17f7f8a0
»
|
dhh |
2005-07-06 |
Made documentation ready fo... |
292 |
# === Association callbacks |
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
293 |
# |
|
2af36bbb
»
|
dhh |
2007-12-05 |
Fix typos (closes #10378) |
294 |
# Similar to the normal callbacks that hook into the lifecycle of an Active Record object, you can also define callbacks that get |
|
7143d801
»
|
Marcel Molina |
2007-11-07 |
Smattering of grammatical f... |
295 |
# triggered when you add an object to or remove an object from an association collection. Example: |
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
296 |
# |
| |
297 |
# class Project |
| |
298 |
# has_and_belongs_to_many :developers, :after_add => :evaluate_velocity |
| |
299 |
# |
| |
300 |
# def evaluate_velocity(developer) |
| |
301 |
# ... |
| |
302 |
# end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
303 |
# end |
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
304 |
# |
| |
305 |
# It's possible to stack callbacks by passing them as an array. Example: |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
306 |
# |
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
307 |
# class Project |
|
17f7f8a0
»
|
dhh |
2005-07-06 |
Made documentation ready fo... |
308 |
# has_and_belongs_to_many :developers, :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}] |
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
309 |
# end |
| |
310 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
311 |
# Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+. |
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
312 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
313 |
# Should any of the +before_add+ callbacks throw an exception, the object does not get added to the collection. Same with |
| |
314 |
# the +before_remove+ callbacks; if an exception is thrown the object doesn't get removed. |
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
315 |
# |
|
8c512a1c
»
|
dhh |
2005-11-03 |
Added extension capabilitie... |
316 |
# === Association extensions |
| |
317 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
318 |
# The proxy objects that control the access to associations can be extended through anonymous modules. This is especially |
|
3c01e01d
»
|
Marcel Molina |
2005-12-19 |
Fix typo in association doc... |
319 |
# beneficial for adding new finders, creators, and other factory-type methods that are only used as part of this association. |
|
8c512a1c
»
|
dhh |
2005-11-03 |
Added extension capabilitie... |
320 |
# Example: |
| |
321 |
# |
| |
322 |
# class Account < ActiveRecord::Base |
|
c8dd66fd
»
|
dhh |
2005-11-06 |
Made association extensions... |
323 |
# has_many :people do |
|
8c512a1c
»
|
dhh |
2005-11-03 |
Added extension capabilitie... |
324 |
# def find_or_create_by_name(name) |
|
e5d9ad3e
»
|
dhh |
2005-12-12 |
Added option inheritance fo... |
325 |
# first_name, last_name = name.split(" ", 2) |
|
da7752e5
»
|
dhh |
2005-11-06 |
Sharper example |
326 |
# find_or_create_by_first_name_and_last_name(first_name, last_name) |
|
8c512a1c
»
|
dhh |
2005-11-03 |
Added extension capabilitie... |
327 |
# end |
|
c8dd66fd
»
|
dhh |
2005-11-06 |
Made association extensions... |
328 |
# end |
|
8c512a1c
»
|
dhh |
2005-11-03 |
Added extension capabilitie... |
329 |
# end |
| |
330 |
# |
| |
331 |
# person = Account.find(:first).people.find_or_create_by_name("David Heinemeier Hansson") |
| |
332 |
# person.first_name # => "David" |
| |
333 |
# person.last_name # => "Heinemeier Hansson" |
| |
334 |
# |
|
c8dd66fd
»
|
dhh |
2005-11-06 |
Made association extensions... |
335 |
# If you need to share the same extensions between many associations, you can use a named extension module. Example: |
| |
336 |
# |
| |
337 |
# module FindOrCreateByNameExtension |
| |
338 |
# def find_or_create_by_name(name) |
|
e5d9ad3e
»
|
dhh |
2005-12-12 |
Added option inheritance fo... |
339 |
# first_name, last_name = name.split(" ", 2) |
|
da7752e5
»
|
dhh |
2005-11-06 |
Sharper example |
340 |
# find_or_create_by_first_name_and_last_name(first_name, last_name) |
|
c8dd66fd
»
|
dhh |
2005-11-06 |
Made association extensions... |
341 |
# end |
| |
342 |
# end |
| |
343 |
# |
| |
344 |
# class Account < ActiveRecord::Base |
| |
345 |
# has_many :people, :extend => FindOrCreateByNameExtension |
| |
346 |
# end |
| |
347 |
# |
| |
348 |
# class Company < ActiveRecord::Base |
| |
349 |
# has_many :people, :extend => FindOrCreateByNameExtension |
| |
350 |
# end |
|
8c512a1c
»
|
dhh |
2005-11-03 |
Added extension capabilitie... |
351 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
352 |
# If you need to use multiple named extension modules, you can specify an array of modules with the <tt>:extend</tt> option. |
|
7e76740d
»
|
technoweenie |
2006-04-10 |
Allow multiple association... |
353 |
# In the case of name conflicts between methods in the modules, methods in modules later in the array supercede |
| |
354 |
# those earlier in the array. Example: |
| |
355 |
# |
| |
356 |
# class Account < ActiveRecord::Base |
| |
357 |
# has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension] |
| |
358 |
# end |
| |
359 |
# |
|
ea51d72e
»
|
technoweenie |
2006-05-28 |
Provide Association Extensi... |
360 |
# Some extensions can only be made to work with knowledge of the association proxy's internals. |
| |
361 |
# Extensions can access relevant state using accessors on the association proxy: |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
362 |
# |
|
ea51d72e
»
|
technoweenie |
2006-05-28 |
Provide Association Extensi... |
363 |
# * +proxy_owner+ - Returns the object the association is part of. |
| |
364 |
# * +proxy_reflection+ - Returns the reflection object that describes the association. |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
365 |
# * +proxy_target+ - Returns the associated object for +belongs_to+ and +has_one+, or the collection of associated objects for +has_many+ and +has_and_belongs_to_many+. |
|
ea51d72e
»
|
technoweenie |
2006-05-28 |
Provide Association Extensi... |
366 |
# |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
367 |
# === Association Join Models |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
368 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
369 |
# Has Many associations can be configured with the <tt>:through</tt> option to use an explicit join model to retrieve the data. This |
| |
370 |
# operates similarly to a +has_and_belongs_to_many+ association. The advantage is that you're able to add validations, |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
371 |
# callbacks, and extra attributes on the join model. Consider the following schema: |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
372 |
# |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
373 |
# class Author < ActiveRecord::Base |
| |
374 |
# has_many :authorships |
| |
375 |
# has_many :books, :through => :authorships |
| |
376 |
# end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
377 |
# |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
378 |
# class Authorship < ActiveRecord::Base |
| |
379 |
# belongs_to :author |
| |
380 |
# belongs_to :book |
| |
381 |
# end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
382 |
# |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
383 |
# @author = Author.find :first |
| |
384 |
# @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to. |
| |
385 |
# @author.books # selects all books by using the Authorship join model |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
386 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
387 |
# You can also go through a +has_many+ association on the join model: |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
388 |
# |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
389 |
# class Firm < ActiveRecord::Base |
| |
390 |
# has_many :clients |
| |
391 |
# has_many :invoices, :through => :clients |
| |
392 |
# end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
393 |
# |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
394 |
# class Client < ActiveRecord::Base |
| |
395 |
# belongs_to :firm |
| |
396 |
# has_many :invoices |
| |
397 |
# end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
398 |
# |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
399 |
# class Invoice < ActiveRecord::Base |
| |
400 |
# belongs_to :client |
| |
401 |
# end |
| |
402 |
# |
| |
403 |
# @firm = Firm.find :first |
| |
404 |
# @firm.clients.collect { |c| c.invoices }.flatten # select all invoices for all clients of the firm |
| |
405 |
# @firm.invoices # selects all invoices by going through the Client join model. |
| |
406 |
# |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
407 |
# === Polymorphic Associations |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
408 |
# |
| |
409 |
# Polymorphic associations on models are not restricted on what types of models they can be associated with. Rather, they |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
410 |
# specify an interface that a +has_many+ association must adhere to. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
411 |
# |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
412 |
# class Asset < ActiveRecord::Base |
| |
413 |
# belongs_to :attachable, :polymorphic => true |
| |
414 |
# end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
415 |
# |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
416 |
# class Post < ActiveRecord::Base |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
417 |
# has_many :assets, :as => :attachable # The :as option specifies the polymorphic interface to use. |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
418 |
# end |
| |
419 |
# |
| |
420 |
# @asset.attachable = @post |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
421 |
# |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
422 |
# This works by using a type column in addition to a foreign key to specify the associated record. In the Asset example, you'd need |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
423 |
# an +attachable_id+ integer column and an +attachable_type+ string column. |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
424 |
# |
|
fc7fd4c5
»
|
dhh |
2006-10-08 |
Docfix (closes #6040) |
425 |
# Using polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
426 |
# for the associations to work as expected, ensure that you store the base model for the STI models in the |
|
fc7fd4c5
»
|
dhh |
2006-10-08 |
Docfix (closes #6040) |
427 |
# type column of the polymorphic association. To continue with the asset example above, suppose there are guest posts |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
428 |
# and member posts that use the posts table for STI. In this case, there must be a +type+ column in the posts table. |
|
fc7fd4c5
»
|
dhh |
2006-10-08 |
Docfix (closes #6040) |
429 |
# |
| |
430 |
# class Asset < ActiveRecord::Base |
| |
431 |
# belongs_to :attachable, :polymorphic => true |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
432 |
# |
|
fc7fd4c5
»
|
dhh |
2006-10-08 |
Docfix (closes #6040) |
433 |
# def attachable_type=(sType) |
| |
434 |
# super(sType.to_s.classify.constantize.base_class.to_s) |
| |
435 |
# end |
| |
436 |
# end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
437 |
# |
|
fc7fd4c5
»
|
dhh |
2006-10-08 |
Docfix (closes #6040) |
438 |
# class Post < ActiveRecord::Base |
| |
439 |
# # because we store "Post" in attachable_type now :dependent => :destroy will work |
| |
440 |
# has_many :assets, :as => :attachable, :dependent => :destroy |
| |
441 |
# end |
| |
442 |
# |
|
aa9ed408
»
|
Marcel Molina |
2007-12-05 |
Fix typo in documentation f... |
443 |
# class GuestPost < Post |
|
fc7fd4c5
»
|
dhh |
2006-10-08 |
Docfix (closes #6040) |
444 |
# end |
| |
445 |
# |
|
aa9ed408
»
|
Marcel Molina |
2007-12-05 |
Fix typo in documentation f... |
446 |
# class MemberPost < Post |
|
fc7fd4c5
»
|
dhh |
2006-10-08 |
Docfix (closes #6040) |
447 |
# end |
| |
448 |
# |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
449 |
# == Caching |
| |
450 |
# |
| |
451 |
# All of the methods are built on a simple caching principle that will keep the result of the last query around unless specifically |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
452 |
# instructed not to. The cache is even shared across methods to make it even cheaper to use the macro-added methods without |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
453 |
# worrying too much about performance at the first go. Example: |
| |
454 |
# |
| |
455 |
# project.milestones # fetches milestones from the database |
| |
456 |
# project.milestones.size # uses the milestone cache |
| |
457 |
# project.milestones.empty? # uses the milestone cache |
| |
458 |
# project.milestones(true).size # fetches milestones from the database |
| |
459 |
# project.milestones # uses the milestone cache |
| |
460 |
# |
|
515886a5
»
|
dhh |
2005-04-18 |
Added documentation for new... |
461 |
# == Eager loading of associations |
| |
462 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
463 |
# Eager loading is a way to find objects of a certain class and a number of named associations. This is |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
464 |
# one of the easiest ways of to prevent the dreaded 1+N problem in which fetching 100 posts that each need to display their author |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
465 |
# triggers 101 database queries. Through the use of eager loading, the 101 queries can be reduced to 2. Example: |
|
515886a5
»
|
dhh |
2005-04-18 |
Added documentation for new... |
466 |
# |
| |
467 |
# class Post < ActiveRecord::Base |
| |
468 |
# belongs_to :author |
| |
469 |
# has_many :comments |
| |
470 |
# end |
| |
471 |
# |
| |
472 |
# Consider the following loop using the class above: |
| |
473 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
474 |
# for post in Post.all |
|
515886a5
»
|
dhh |
2005-04-18 |
Added documentation for new... |
475 |
# puts "Post: " + post.title |
| |
476 |
# puts "Written by: " + post.author.name |
| |
477 |
# puts "Last comment on: " + post.comments.first.created_on |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
478 |
# end |
|
515886a5
»
|
dhh |
2005-04-18 |
Added documentation for new... |
479 |
# |
| |
480 |
# To iterate over these one hundred posts, we'll generate 201 database queries. Let's first just optimize it for retrieving the author: |
| |
481 |
# |
|
4e2f7bec
»
|
dhh |
2005-04-19 |
Added documentation about :... |
482 |
# for post in Post.find(:all, :include => :author) |
|
515886a5
»
|
dhh |
2005-04-18 |
Added documentation for new... |
483 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
484 |
# This references the name of the +belongs_to+ association that also used the <tt>:author</tt> symbol. After loading the posts, find |
| |
485 |
# will collect the +author_id+ from each one and load all the referenced authors with one query. Doing so will cut down the number of queries from 201 to 102. |
|
515886a5
»
|
dhh |
2005-04-18 |
Added documentation for new... |
486 |
# |
| |
487 |
# We can improve upon the situation further by referencing both associations in the finder with: |
| |
488 |
# |
|
4e2f7bec
»
|
dhh |
2005-04-19 |
Added documentation about :... |
489 |
# for post in Post.find(:all, :include => [ :author, :comments ]) |
|
515886a5
»
|
dhh |
2005-04-18 |
Added documentation for new... |
490 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
491 |
# This will load all comments with a single query. This reduces the total number of queries to 3. More generally the number of queries |
| |
492 |
# will be 1 plus the number of associations named (except if some of the associations are polymorphic +belongs_to+ - see below). |
|
5b414190
»
|
jeremy |
2007-05-19 |
Document deep eager include... |
493 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
494 |
# To include a deep hierarchy of associations, use a hash: |
|
5b414190
»
|
jeremy |
2007-05-19 |
Document deep eager include... |
495 |
# |
| |
496 |
# for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ]) |
| |
497 |
# |
| |
498 |
# That'll grab not only all the comments but all their authors and gravatar pictures. You can mix and match |
| |
499 |
# symbols, arrays and hashes in any combination to describe the associations you want to load. |
| |
500 |
# |
| |
501 |
# All of this power shouldn't fool you into thinking that you can pull out huge amounts of data with no performance penalty just because you've reduced |
|
a8eea0b0
»
|
dhh |
2005-10-26 |
Fix docs (closes #2491) |
502 |
# the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it's no |
| |
503 |
# catch-all for performance problems, but it's a great way to cut down on the number of queries in a situation as the one described above. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
504 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
505 |
# Since only one table is loaded at a time, conditions or orders cannot reference tables other than the main one. If this is the case |
| |
506 |
# Active Record falls back to the previously used LEFT OUTER JOIN based strategy. For example |
| |
507 |
# |
| |
508 |
# Post.find(:all, :include => [ :author, :comments ], :conditions => ['comments.approved = ?', true]) |
|
515886a5
»
|
dhh |
2005-04-18 |
Added documentation for new... |
509 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
510 |
# will result in a single SQL query with joins along the lines of: <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and |
| |
511 |
# <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Note that using conditions like this can have unintended consequences. |
| |
512 |
# In the above example posts with no approved comments are not returned at all, because the conditions apply to the SQL statement as a whole |
| |
513 |
# and not just to the association. You must disambiguate column references for this fallback to happen, for example |
| |
514 |
# <tt>:order => "author.name DESC"</tt> will work but <tt>:order => "name DESC"</tt> will not. |
| |
515 |
# |
| |
516 |
# If you do want eagerload only some members of an association it is usually more natural to <tt>:include</tt> an association |
| |
517 |
# which has conditions defined on it: |
| |
518 |
# |
| |
519 |
# class Post < ActiveRecord::Base |
| |
520 |
# has_many :approved_comments, :class_name => 'Comment', :conditions => ['approved = ?', true] |
| |
521 |
# end |
| |
522 |
# |
| |
523 |
# Post.find(:all, :include => :approved_comments) |
| |
524 |
# |
| |
525 |
# will load posts and eager load the +approved_comments+ association, which contains only those comments that have been approved. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
526 |
# |
|
dc37fdc4
»
|
lifo |
2008-11-02 |
Merge docrails. Remove unne... |
527 |
# If you eager load an association with a specified <tt>:limit</tt> option, it will be ignored, returning all the associated objects: |
| |
528 |
# |
| |
529 |
# class Picture < ActiveRecord::Base |
| |
530 |
# has_many :most_recent_comments, :class_name => 'Comment', :order => 'id DESC', :limit => 10 |
| |
531 |
# end |
| |
532 |
# |
| |
533 |
# Picture.find(:first, :include => :most_recent_comments).most_recent_comments # => returns all associated comments. |
| |
534 |
# |
|
78704946
»
|
technoweenie |
2006-10-11 |
Restore eager condition int... |
535 |
# When eager loaded, conditions are interpolated in the context of the model class, not the model instance. Conditions are lazily interpolated |
| |
536 |
# before the actual model exists. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
537 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
538 |
# Eager loading is supported with polymorphic associations. |
|
752f633b
»
|
jeremy |
2008-01-04 |
Document that eager loading... |
539 |
# |
| |
540 |
# class Address < ActiveRecord::Base |
| |
541 |
# belongs_to :addressable, :polymorphic => true |
| |
542 |
# end |
| |
543 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
544 |
# A call that tries to eager load the addressable model |
|
752f633b
»
|
jeremy |
2008-01-04 |
Document that eager loading... |
545 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
546 |
# Address.find(:all, :include => :addressable) |
|
b2fa70a8
»
|
Marcel Molina |
2008-01-23 |
Indicate in documentation t... |
547 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
548 |
# will execute one query to load the addresses and load the addressables with one query per addressable type. |
| |
549 |
# For example if all the addressables are either of class Person or Company then a total of 3 queries will be executed. The list of |
| |
550 |
# addressable types to load is determined on the back of the addresses loaded. This is not supported if Active Record has to fallback |
| |
551 |
# to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError. The reason is that the parent |
| |
552 |
# model's type is a column value so its corresponding table name cannot be put in the +FROM+/+JOIN+ clauses of that query. |
|
752f633b
»
|
jeremy |
2008-01-04 |
Document that eager loading... |
553 |
# |
|
ed10f873
»
|
technoweenie |
2006-03-22 |
STI associations are now al... |
554 |
# == Table Aliasing |
| |
555 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
556 |
# Active Record uses table aliasing in the case that a table is referenced multiple times in a join. If a table is referenced only once, |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
557 |
# the standard table name is used. The second time, the table is aliased as <tt>#{reflection_name}_#{parent_table_name}</tt>. Indexes are appended |
|
ed10f873
»
|
technoweenie |
2006-03-22 |
STI associations are now al... |
558 |
# for any more successive uses of the table name. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
559 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
560 |
# Post.find :all, :joins => :comments |
| |
561 |
# # => SELECT ... FROM posts INNER JOIN comments ON ... |
| |
562 |
# Post.find :all, :joins => :special_comments # STI |
| |
563 |
# # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment' |
| |
564 |
# Post.find :all, :joins => [:comments, :special_comments] # special_comments is the reflection name, posts is the parent table name |
| |
565 |
# # => SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
566 |
# |
|
ed10f873
»
|
technoweenie |
2006-03-22 |
STI associations are now al... |
567 |
# Acts as tree example: |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
568 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
569 |
# TreeMixin.find :all, :joins => :children |
| |
570 |
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ... |
| |
571 |
# TreeMixin.find :all, :joins => {:children => :parent} |
| |
572 |
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ... |
| |
573 |
# INNER JOIN parents_mixins ... |
| |
574 |
# TreeMixin.find :all, :joins => {:children => {:parent => :children}} |
| |
575 |
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ... |
| |
576 |
# INNER JOIN parents_mixins ... |
| |
577 |
# INNER JOIN mixins childrens_mixins_2 |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
578 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
579 |
# Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix: |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
580 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
581 |
# Post.find :all, :joins => :categories |
| |
582 |
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ... |
| |
583 |
# Post.find :all, :joins => {:categories => :posts} |
| |
584 |
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ... |
| |
585 |
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories |
| |
586 |
# Post.find :all, :joins => {:categories => {:posts => :categories}} |
| |
587 |
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ... |
| |
588 |
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories |
| |
589 |
# INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2 |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
590 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
591 |
# If you wish to specify your own custom joins using a <tt>:joins</tt> option, those table names will take precedence over the eager associations: |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
592 |
# |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
593 |
# Post.find :all, :joins => :comments, :joins => "inner join comments ..." |
| |
594 |
# # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ... |
| |
595 |
# Post.find :all, :joins => [:comments, :special_comments], :joins => "inner join comments ..." |
| |
596 |
# # => SELECT ... FROM posts INNER JOIN comments comments_posts ON ... |
| |
597 |
# INNER JOIN comments special_comments_posts ... |
|
ed10f873
»
|
technoweenie |
2006-03-22 |
STI associations are now al... |
598 |
# INNER JOIN comments ... |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
599 |
# |
|
ed10f873
»
|
technoweenie |
2006-03-22 |
STI associations are now al... |
600 |
# Table aliases are automatically truncated according to the maximum length of table identifiers according to the specific database. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
601 |
# |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
602 |
# == Modules |
| |
603 |
# |
| |
604 |
# By default, associations will look for objects within the current module scope. Consider: |
| |
605 |
# |
| |
606 |
# module MyApplication |
| |
607 |
# module Business |
| |
608 |
# class Firm < ActiveRecord::Base |
| |
609 |
# has_many :clients |
| |
610 |
# end |
| |
611 |
# |
|
0432d151
»
|
lifo |
2008-07-16 |
Merge with docrails.  |
612 |
# class Client < ActiveRecord::Base; end |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
613 |
# end |
| |
614 |
# end |
| |
615 |
# |
|
0432d151
»
|
lifo |
2008-07-16 |
Merge with docrails.  |
616 |
# When <tt>Firm#clients</tt> is called, it will in turn call <tt>MyApplication::Business::Client.find_all_by_firm_id(firm.id)</tt>. |
| |
617 |
# If you want to associate with a class in another module scope, this can be done by specifying the complete class name. |
| |
618 |
# Example: |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
619 |
# |
| |
620 |
# module MyApplication |
| |
621 |
# module Business |
| |
622 |
# class Firm < ActiveRecord::Base; end |
| |
623 |
# end |
| |
624 |
# |
| |
625 |
# module Billing |
| |
626 |
# class Account < ActiveRecord::Base |
| |
627 |
# belongs_to :firm, :class_name => "MyApplication::Business::Firm" |
| |
628 |
# end |
| |
629 |
# end |
| |
630 |
# end |
| |
631 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
632 |
# == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt> |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
633 |
# |
| |
634 |
# If you attempt to assign an object to an association that doesn't match the inferred or specified <tt>:class_name</tt>, you'll |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
635 |
# get an <tt>ActiveRecord::AssociationTypeMismatch</tt>. |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
636 |
# |
| |
637 |
# == Options |
| |
638 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
639 |
# All of the association macros can be specialized through options. This makes cases more complex than the simple and guessable ones |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
640 |
# possible. |
| |
641 |
module ClassMethods |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
642 |
# Specifies a one-to-many association. The following methods for retrieval and query of |
| |
643 |
# collections of associated objects will be added: |
| |
644 |
# |
| |
645 |
# [collection(force_reload = false)] |
| |
646 |
# Returns an array of all the associated objects. |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
647 |
# An empty array is returned if none are found. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
648 |
# [collection<<(object, ...)] |
| |
649 |
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key. |
| |
650 |
# [collection.delete(object, ...)] |
| |
651 |
# Removes one or more objects from the collection by setting their foreign keys to +NULL+. |
|
a03e2b35
»
|
lifo |
2008-10-21 |
Merge with docrails. Also a... |
652 |
# Objects will be in addition destroyed if they're associated with <tt>:dependent => :destroy</tt>, |
| |
653 |
# and deleted if they're associated with <tt>:dependent => :delete_all</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
654 |
# [collection=objects] |
| |
655 |
# Replaces the collections content by deleting and adding objects as appropriate. |
| |
656 |
# [collection_singular_ids] |
| |
657 |
# Returns an array of the associated objects' ids |
| |
658 |
# [collection_singular_ids=ids] |
| |
659 |
# Replace the collection with the objects identified by the primary keys in +ids+ |
| |
660 |
# [collection.clear] |
| |
661 |
# Removes every object from the collection. This destroys the associated objects if they |
| |
662 |
# are associated with <tt>:dependent => :destroy</tt>, deletes them directly from the |
| |
663 |
# database if <tt>:dependent => :delete_all</tt>, otherwise sets their foreign keys to +NULL+. |
| |
664 |
# [collection.empty?] |
| |
665 |
# Returns +true+ if there are no associated objects. |
| |
666 |
# [collection.size] |
| |
667 |
# Returns the number of associated objects. |
| |
668 |
# [collection.find(...)] |
| |
669 |
# Finds an associated object according to the same rules as ActiveRecord::Base.find. |
|
c3f53f41
»
|
lifo |
2008-12-19 |
Merge docrails |
670 |
# [collection.exists?(...)] |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
671 |
# Checks whether an associated object with the given conditions exists. |
| |
672 |
# Uses the same rules as ActiveRecord::Base.exists?. |
| |
673 |
# [collection.build(attributes = {}, ...)] |
| |
674 |
# Returns one or more new objects of the collection type that have been instantiated |
| |
675 |
# with +attributes+ and linked to this object through a foreign key, but have not yet |
| |
676 |
# been saved. <b>Note:</b> This only works if an associated object already exists, not if |
| |
677 |
# it's +nil+! |
| |
678 |
# [collection.create(attributes = {})] |
| |
679 |
# Returns a new object of the collection type that has been instantiated |
| |
680 |
# with +attributes+, linked to this object through a foreign key, and that has already |
| |
681 |
# been saved (if it passed the validation). <b>Note:</b> This only works if an associated |
| |
682 |
# object already exists, not if it's +nil+! |
| |
683 |
# |
| |
684 |
# (*Note*: +collection+ is replaced with the symbol passed as the first argument, so |
| |
685 |
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.) |
| |
686 |
# |
| |
687 |
# === Example |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
688 |
# |
|
6ef35461
»
|
lifo |
2008-09-03 |
Merge docrails |
689 |
# Example: A Firm class declares <tt>has_many :clients</tt>, which will add: |
| |
690 |
# * <tt>Firm#clients</tt> (similar to <tt>Clients.find :all, :conditions => ["firm_id = ?", id]</tt>) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
691 |
# * <tt>Firm#clients<<</tt> |
| |
692 |
# * <tt>Firm#clients.delete</tt> |
|
bfe6a759
»
|
dhh |
2005-06-15 |
Added actual database-chang... |
693 |
# * <tt>Firm#clients=</tt> |
|
cb0837a2
»
|
dhh |
2006-10-08 |
Doc fixes (closes #6325) |
694 |
# * <tt>Firm#client_ids</tt> |
|
bfe6a759
»
|
dhh |
2005-06-15 |
Added actual database-chang... |
695 |
# * <tt>Firm#client_ids=</tt> |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
696 |
# * <tt>Firm#clients.clear</tt> |
| |
697 |
# * <tt>Firm#clients.empty?</tt> (similar to <tt>firm.clients.size == 0</tt>) |
| |
698 |
# * <tt>Firm#clients.size</tt> (similar to <tt>Client.count "firm_id = #{id}"</tt>) |
|
c1611a70
»
|
dhh |
2005-04-18 |
Updated documentation here ... |
699 |
# * <tt>Firm#clients.find</tt> (similar to <tt>Client.find(id, :conditions => "firm_id = #{id}")</tt>) |
|
c3f53f41
»
|
lifo |
2008-12-19 |
Merge docrails |
700 |
# * <tt>Firm#clients.exists?(:name => 'ACME')</tt> (similar to <tt>Client.exists?(:name => 'ACME', :firm_id => firm.id)</tt>) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
701 |
# * <tt>Firm#clients.build</tt> (similar to <tt>Client.new("firm_id" => id)</tt>) |
|
1d4d7217
»
|
dhh |
2005-06-21 |
Fixed docs #856 |
702 |
# * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save; c</tt>) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
703 |
# The declaration can also include an options hash to specialize the behavior of the association. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
704 |
# |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
705 |
# === Supported options |
| |
706 |
# [:class_name] |
| |
707 |
# Specify the class name of the association. Use it only if that name can't be inferred |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
708 |
# from the association name. So <tt>has_many :products</tt> will by default be linked to the Product class, but |
| |
709 |
# if the real class name is SpecialProduct, you'll have to specify it with this option. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
710 |
# [:conditions] |
| |
711 |
# Specify the conditions that the associated objects must meet in order to be included as a +WHERE+ |
|
c23c9bd1
»
|
technoweenie |
2008-03-21 |
Allow association scoping f... |
712 |
# SQL fragment, such as <tt>price > 5 AND name LIKE 'B%'</tt>. Record creations from the association are scoped if a hash |
| |
713 |
# is used. <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt> |
| |
714 |
# or <tt>@blog.posts.build</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
715 |
# [:order] |
| |
716 |
# Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment, |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
717 |
# such as <tt>last_name, first_name DESC</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
718 |
# [:foreign_key] |
| |
719 |
# Specify the foreign key used for the association. By default this is guessed to be the name |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
720 |
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+ association will use "person_id" |
| |
721 |
# as the default <tt>:foreign_key</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
722 |
# [:primary_key] |
| |
723 |
# Specify the method that returns the primary key used for the association. By default this is +id+. |
| |
724 |
# [:dependent] |
| |
725 |
# If set to <tt>:destroy</tt> all the associated objects are destroyed |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
726 |
# alongside this object by calling their +destroy+ method. If set to <tt>:delete_all</tt> all associated |
| |
727 |
# objects are deleted *without* calling their +destroy+ method. If set to <tt>:nullify</tt> all associated |
| |
728 |
# objects' foreign keys are set to +NULL+ *without* calling their +save+ callbacks. *Warning:* This option is ignored when also using |
| |
729 |
# the <tt>:through</tt> option. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
730 |
# [:finder_sql] |
| |
731 |
# Specify a complete SQL statement to fetch the association. This is a good way to go for complex |
|
a8eea0b0
»
|
dhh |
2005-10-26 |
Fix docs (closes #2491) |
732 |
# associations that depend on multiple tables. Note: When this option is used, +find_in_collection+ is _not_ added. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
733 |
# [:counter_sql] |
| |
734 |
# Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is |
|
7143d801
»
|
Marcel Molina |
2007-11-07 |
Smattering of grammatical f... |
735 |
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
736 |
# [:extend] |
| |
737 |
# Specify a named module for extending the proxy. See "Association extensions". |
| |
738 |
# [:include] |
| |
739 |
# Specify second-order associations that should be eager loaded when the collection is loaded. |
| |
740 |
# [:group] |
| |
741 |
# An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause. |
|
97403ad5
»
|
miloops |
2008-11-21 |
Add :having option to find,... |
742 |
# [:having] |
| |
743 |
# Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns. Uses the <tt>HAVING</tt> SQL-clause. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
744 |
# [:limit] |
| |
745 |
# An integer determining the limit on the number of rows that should be returned. |
| |
746 |
# [:offset] |
| |
747 |
# An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows. |
| |
748 |
# [:select] |
| |
749 |
# By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if you, for example, want to do a join |
|
3351d299
»
|
indirect |
2008-05-31 |
Add has_many :primary_key o... |
750 |
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
751 |
# [:as] |
| |
752 |
# Specifies a polymorphic interface (See <tt>belongs_to</tt>). |
| |
753 |
# [:through] |
| |
754 |
# Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt> |
|
9f51eb24
»
|
jeremy |
2007-05-22 |
Fix :through docs wrecked u... |
755 |
# are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a <tt>belongs_to</tt> |
| |
756 |
# or <tt>has_many</tt> association on the join model. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
757 |
# [:source] |
| |
758 |
# Specifies the source association name used by <tt>has_many :through</tt> queries. Only use it if the name cannot be |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
759 |
# inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either <tt>:subscribers</tt> or |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
760 |
# <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
761 |
# [:source_type] |
| |
762 |
# Specifies type of the source association used by <tt>has_many :through</tt> queries where the source |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
763 |
# association is a polymorphic +belongs_to+. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
764 |
# [:uniq] |
| |
765 |
# If true, duplicates will be omitted from the collection. Useful in conjunction with <tt>:through</tt>. |
| |
766 |
# [:readonly] |
| |
767 |
# If true, all the associated objects are readonly through the association. |
| |
768 |
# [:validate] |
| |
769 |
# If false, don't validate the associated objects when saving the parent object. true by default. |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
770 |
# [:autosave] |
| |
771 |
# If true, always save any loaded members and destroy members marked for destruction, when saving the parent object. Off by default. |
| |
772 |
# |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
773 |
# Option examples: |
| |
774 |
# has_many :comments, :order => "posted_on" |
|
49c801b7
»
|
dhh |
2005-11-06 |
Added :include as an option... |
775 |
# has_many :comments, :include => :author |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
776 |
# has_many :people, :class_name => "Person", :conditions => "deleted = 0", :order => "name" |
|
57565b35
»
|
NZKoz |
2006-03-09 |
format fix for locking [Mic... |
777 |
# has_many :tracks, :order => "position", :dependent => :destroy |
| |
778 |
# has_many :comments, :dependent => :nullify |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
779 |
# has_many :tags, :as => :taggable |
|
dfa78663
»
|
jeremy |
2008-02-12 |
Introduce the :readonly opt... |
780 |
# has_many :reports, :readonly => true |
|
38bae0a9
»
|
technoweenie |
2006-03-24 |
Change has_many :through to... |
781 |
# has_many :subscribers, :through => :subscriptions, :source => :user |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
782 |
# has_many :subscribers, :class_name => "Person", :finder_sql => |
| |
783 |
# 'SELECT DISTINCT people.* ' + |
| |
784 |
# 'FROM people p, post_subscriptions ps ' + |
| |
785 |
# 'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' + |
| |
786 |
# 'ORDER BY p.first_name' |
|
c8dd66fd
»
|
dhh |
2005-11-06 |
Made association extensions... |
787 |
def has_many(association_id, options = {}, &extension) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
788 |
reflection = create_has_many_reflection(association_id, options, &extension) |
| |
789 |
configure_dependency_for_has_many(reflection) |
|
f6b12c11
»
|
lifo |
2008-04-05 |
Refactor HasManyThroughAsso... |
790 |
add_association_callbacks(reflection.name, reflection.options) |
| |
791 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
792 |
if options[:through] |
|
f6b12c11
»
|
lifo |
2008-04-05 |
Refactor HasManyThroughAsso... |
793 |
collection_accessor_methods(reflection, HasManyThroughAssociation) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
794 |
else |
| |
795 |
collection_accessor_methods(reflection, HasManyAssociation) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
796 |
end |
| |
797 |
end |
| |
798 |
|
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
799 |
# Specifies a one-to-one association with another class. This method should only be used |
| |
800 |
# if the other class contains the foreign key. If the current class contains the foreign key, |
| |
801 |
# then you should use +belongs_to+ instead. See also ActiveRecord::Associations::ClassMethods's overview |
| |
802 |
# on when to use has_one and when to use belongs_to. |
| |
803 |
# |
| |
804 |
# The following methods for retrieval and query of a single associated object will be added: |
| |
805 |
# |
| |
806 |
# [association(force_reload = false)] |
| |
807 |
# Returns the associated object. +nil+ is returned if none is found. |
| |
808 |
# [association=(associate)] |
| |
809 |
# Assigns the associate object, extracts the primary key, sets it as the foreign key, |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
810 |
# and saves the associate object. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
811 |
# [build_association(attributes = {})] |
| |
812 |
# Returns a new object of the associated type that has been instantiated |
| |
813 |
# with +attributes+ and linked to this object through a foreign key, but has not |
| |
814 |
# yet been saved. <b>Note:</b> This ONLY works if an association already exists. |
| |
815 |
# It will NOT work if the association is +nil+. |
| |
816 |
# [create_association(attributes = {})] |
| |
817 |
# Returns a new object of the associated type that has been instantiated |
| |
818 |
# with +attributes+, linked to this object through a foreign key, and that |
| |
819 |
# has already been saved (if it passed the validation). |
| |
820 |
# |
| |
821 |
# (+association+ is replaced with the symbol passed as the first argument, so |
| |
822 |
# <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
823 |
# |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
824 |
# === Example |
| |
825 |
# |
| |
826 |
# An Account class declares <tt>has_one :beneficiary</tt>, which will add: |
|
3dfa56cc
»
|
dhh |
2005-06-26 |
Updated all references to t... |
827 |
# * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.find(:first, :conditions => "account_id = #{id}")</tt>) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
828 |
# * <tt>Account#beneficiary=(beneficiary)</tt> (similar to <tt>beneficiary.account_id = account.id; beneficiary.save</tt>) |
|
3b9e90a4
»
|
dhh |
2005-04-11 |
Moved build_association and... |
829 |
# * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new("account_id" => id)</tt>) |
| |
830 |
# * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save; b</tt>) |
| |
831 |
# |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
832 |
# === Options |
| |
833 |
# |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
834 |
# The declaration can also include an options hash to specialize the behavior of the association. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
835 |
# |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
836 |
# Options are: |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
837 |
# [:class_name] |
| |
838 |
# Specify the class name of the association. Use it only if that name can't be inferred |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
839 |
# from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but |
| |
840 |
# if the real class name is Person, you'll have to specify it with this option. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
841 |
# [:conditions] |
| |
842 |
# Specify the conditions that the associated object must meet in order to be included as a +WHERE+ |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
843 |
# SQL fragment, such as <tt>rank = 5</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
844 |
# [:order] |
| |
845 |
# Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment, |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
846 |
# such as <tt>last_name, first_name DESC</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
847 |
# [:dependent] |
| |
848 |
# If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
849 |
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to <tt>:nullify</tt>, the associated |
| |
850 |
# object's foreign key is set to +NULL+. Also, association is assigned. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
851 |
# [:foreign_key] |
| |
852 |
# Specify the foreign key used for the association. By default this is guessed to be the name |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
853 |
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association will use "person_id" |
| |
854 |
# as the default <tt>:foreign_key</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
855 |
# [:primary_key] |
| |
856 |
# Specify the method that returns the primary key used for the association. By default this is +id+. |
| |
857 |
# [:include] |
| |
858 |
# Specify second-order associations that should be eager loaded when this object is loaded. |
| |
859 |
# [:as] |
| |
860 |
# Specifies a polymorphic interface (See <tt>belongs_to</tt>). |
| |
861 |
# [:select] |
| |
862 |
# By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join |
|
8d0b4fa3
»
|
josevalim |
2008-05-23 |
Added :select option to has... |
863 |
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
864 |
# [:through] |
| |
865 |
# Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt> and <tt>:foreign_key</tt> |
|
273b21fa
»
|
technoweenie |
2008-03-21 |
Add has_one :through suppor... |
866 |
# are ignored, as the association uses the source reflection. You can only use a <tt>:through</tt> query through a |
| |
867 |
# <tt>has_one</tt> or <tt>belongs_to</tt> association on the join model. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
868 |
# [:source] |
| |
869 |
# Specifies the source association name used by <tt>has_one :through</tt> queries. Only use it if the name cannot be |
|
273b21fa
»
|
technoweenie |
2008-03-21 |
Add has_one :through suppor... |
870 |
# inferred from the association. <tt>has_one :favorite, :through => :favorites</tt> will look for a |
|
5cda000b
»
|
dhh |
2009-02-27 |
Fixed that autosave should ...  |
871 |
# <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
872 |
# [:source_type] |
| |
873 |
# Specifies type of the source association used by <tt>has_one :through</tt> queries where the source |
|
5cda000b
»
|
dhh |
2009-02-27 |
Fixed that autosave should ...  |
874 |
# association is a polymorphic +belongs_to+. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
875 |
# [:readonly] |
| |
876 |
# If true, the associated object is readonly through the association. |
| |
877 |
# [:validate] |
| |
878 |
# If false, don't validate the associated object when saving the parent object. +false+ by default. |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
879 |
# [:autosave] |
| |
880 |
# If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. Off by default. |
|
dfa78663
»
|
jeremy |
2008-02-12 |
Introduce the :readonly opt... |
881 |
# |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
882 |
# Option examples: |
|
57565b35
»
|
NZKoz |
2006-03-09 |
format fix for locking [Mic... |
883 |
# has_one :credit_card, :dependent => :destroy # destroys the associated credit card |
|
7143d801
»
|
Marcel Molina |
2007-11-07 |
Smattering of grammatical f... |
884 |
# has_one :credit_card, :dependent => :nullify # updates the associated records foreign key value to NULL rather than destroying it |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
885 |
# has_one :last_comment, :class_name => "Comment", :order => "posted_on" |
| |
886 |
# has_one :project_manager, :class_name => "Person", :conditions => "role = 'project_manager'" |
|
21399219
»
|
technoweenie |
2006-05-22 |
Add docs for the :as option... |
887 |
# has_one :attachment, :as => :attachable |
|
dfa78663
»
|
jeremy |
2008-02-12 |
Introduce the :readonly opt... |
888 |
# has_one :boss, :readonly => :true |
|
273b21fa
»
|
technoweenie |
2008-03-21 |
Add has_one :through suppor... |
889 |
# has_one :club, :through => :membership |
| |
890 |
# has_one :primary_address, :through => :addressables, :conditions => ["addressable.primary = ?", true], :source => :addressable |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
891 |
def has_one(association_id, options = {}) |
|
273b21fa
»
|
technoweenie |
2008-03-21 |
Add has_one :through suppor... |
892 |
if options[:through] |
| |
893 |
reflection = create_has_one_through_reflection(association_id, options) |
| |
894 |
association_accessor_methods(reflection, ActiveRecord::Associations::HasOneThroughAssociation) |
| |
895 |
else |
| |
896 |
reflection = create_has_one_reflection(association_id, options) |
| |
897 |
association_accessor_methods(reflection, HasOneAssociation) |
| |
898 |
association_constructor_method(:build, reflection, HasOneAssociation) |
| |
899 |
association_constructor_method(:create, reflection, HasOneAssociation) |
| |
900 |
configure_dependency_for_has_one(reflection) |
| |
901 |
end |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
902 |
end |
| |
903 |
|
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
904 |
# Specifies a one-to-one association with another class. This method should only be used |
| |
905 |
# if this class contains the foreign key. If the other class contains the foreign key, |
| |
906 |
# then you should use +has_one+ instead. See also ActiveRecord::Associations::ClassMethods's overview |
| |
907 |
# on when to use +has_one+ and when to use +belongs_to+. |
| |
908 |
# |
| |
909 |
# Methods will be added for retrieval and query for a single associated object, for which |
| |
910 |
# this object holds an id: |
| |
911 |
# |
| |
912 |
# [association(force_reload = false)] |
| |
913 |
# Returns the associated object. +nil+ is returned if none is found. |
| |
914 |
# [association=(associate)] |
| |
915 |
# Assigns the associate object, extracts the primary key, and sets it as the foreign key. |
| |
916 |
# [build_association(attributes = {})] |
| |
917 |
# Returns a new object of the associated type that has been instantiated |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
918 |
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
919 |
# [create_association(attributes = {})] |
| |
920 |
# Returns a new object of the associated type that has been instantiated |
| |
921 |
# with +attributes+, linked to this object through a foreign key, and that |
| |
922 |
# has already been saved (if it passed the validation). |
| |
923 |
# |
| |
924 |
# (+association+ is replaced with the symbol passed as the first argument, so |
| |
925 |
# <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
926 |
# |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
927 |
# === Example |
| |
928 |
# |
| |
929 |
# A Post class declares <tt>belongs_to :author</tt>, which will add: |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
930 |
# * <tt>Post#author</tt> (similar to <tt>Author.find(author_id)</tt>) |
| |
931 |
# * <tt>Post#author=(author)</tt> (similar to <tt>post.author_id = author.id</tt>) |
| |
932 |
# * <tt>Post#author?</tt> (similar to <tt>post.author == some_author</tt>) |
|
1d4d7217
»
|
dhh |
2005-06-21 |
Fixed docs #856 |
933 |
# * <tt>Post#build_author</tt> (similar to <tt>post.author = Author.new</tt>) |
| |
934 |
# * <tt>Post#create_author</tt> (similar to <tt>post.author = Author.new; post.author.save; post.author</tt>) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
935 |
# The declaration can also include an options hash to specialize the behavior of the association. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
936 |
# |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
937 |
# === Options |
| |
938 |
# |
| |
939 |
# [:class_name] |
| |
940 |
# Specify the class name of the association. Use it only if that name can't be inferred |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
941 |
# from the association name. So <tt>has_one :author</tt> will by default be linked to the Author class, but |
| |
942 |
# if the real class name is Person, you'll have to specify it with this option. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
943 |
# [:conditions] |
| |
944 |
# Specify the conditions that the associated object must meet in order to be included as a +WHERE+ |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
945 |
# SQL fragment, such as <tt>authorized = 1</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
946 |
# [:select] |
| |
947 |
# By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join |
|
8d0b4fa3
»
|
josevalim |
2008-05-23 |
Added :select option to has... |
948 |
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
949 |
# [:foreign_key] |
| |
950 |
# Specify the foreign key used for the association. By default this is guessed to be the name |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
951 |
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt> association will use |
| |
952 |
# "person_id" as the default <tt>:foreign_key</tt>. Similarly, <tt>belongs_to :favorite_person, :class_name => "Person"</tt> |
| |
953 |
# will use a foreign key of "favorite_person_id". |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
954 |
# [:dependent] |
| |
955 |
# If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to |
|
16b129a6
»
|
jeremy |
2008-01-18 |
belongs_to supports :depend... |
956 |
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. This option should not be specified when |
| |
957 |
# <tt>belongs_to</tt> is used in conjunction with a <tt>has_many</tt> relationship on another class because of the potential to leave |
| |
958 |
# orphaned records behind. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
959 |
# [:counter_cache] |
| |
960 |
# Caches the number of belonging objects on the associate class through the use of +increment_counter+ |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
961 |
# and +decrement_counter+. The counter cache is incremented when an object of this class is created and decremented when it's |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
962 |
# destroyed. This requires that a column named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class) |
| |
963 |
# is used on the associate class (such as a Post class). You can also specify a custom counter cache column by providing |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
964 |
# a column name instead of a +true+/+false+ value to this option (e.g., <tt>:counter_cache => :my_custom_counter</tt>.) |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
965 |
# Note: Specifying a counter cache will add it to that model's list of readonly attributes using +attr_readonly+. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
966 |
# [:include] |
| |
967 |
# Specify second-order associations that should be eager loaded when this object is loaded. |
| |
968 |
# [:polymorphic] |
| |
969 |
# Specify this association is a polymorphic association by passing +true+. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
970 |
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
971 |
# to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>). |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
972 |
# [:readonly] |
| |
973 |
# If true, the associated object is readonly through the association. |
| |
974 |
# [:validate] |
| |
975 |
# If false, don't validate the associated objects when saving the parent object. +false+ by default. |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
976 |
# [:autosave] |
| |
977 |
# If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. Off by default. |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
978 |
# |
| |
979 |
# Option examples: |
| |
980 |
# belongs_to :firm, :foreign_key => "client_of" |
| |
981 |
# belongs_to :author, :class_name => "Person", :foreign_key => "author_id" |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
982 |
# belongs_to :valid_coupon, :class_name => "Coupon", :foreign_key => "coupon_id", |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
983 |
# :conditions => 'discounts > #{payments_count}' |
|
2597bd69
»
|
technoweenie |
2006-03-27 |
documentation for polymorph... |
984 |
# belongs_to :attachable, :polymorphic => true |
|
dfa78663
»
|
jeremy |
2008-02-12 |
Introduce the :readonly opt... |
985 |
# belongs_to :project, :readonly => true |
|
54213dad
»
|
dhh |
2008-03-19 |
Docfixes (closes #11356, #1... |
986 |
# belongs_to :post, :counter_cache => true |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
987 |
def belongs_to(association_id, options = {}) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
988 |
reflection = create_belongs_to_reflection(association_id, options) |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
989 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
990 |
if reflection.options[:polymorphic] |
| |
991 |
association_accessor_methods(reflection, BelongsToPolymorphicAssociation) |
|
57b7532b
»
|
dhh |
2005-12-01 |
Work-in progress for provid... |
992 |
else |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
993 |
association_accessor_methods(reflection, BelongsToAssociation) |
| |
994 |
association_constructor_method(:build, reflection, BelongsToAssociation) |
| |
995 |
association_constructor_method(:create, reflection, BelongsToAssociation) |
|
57b7532b
»
|
dhh |
2005-12-01 |
Work-in progress for provid... |
996 |
end |
|
964b67dd
»
|
jamis |
2006-03-04 |
Make counter_cache work wit... |
997 |
|
|
2a305949
»
|
technoweenie |
2007-03-27 |
documentation project patch... |
998 |
# Create the callbacks to update counter cache |
|
964b67dd
»
|
jamis |
2006-03-04 |
Make counter_cache work wit... |
999 |
if options[:counter_cache] |
|
87898bad
»
|
jamis |
2006-03-09 |
Allow counter_cache to acce... |
1000 |
cache_column = options[:counter_cache] == true ? |
|
de96a866
»
|
adevadeh |
2008-09-12 |
applied patch to fix the as... |
1001 |
"#{self.to_s.demodulize.underscore.pluralize}_count" : |
|
87898bad
»
|
jamis |
2006-03-09 |
Allow counter_cache to acce... |
1002 |
options[:counter_cache] |
| |
1003 |
|
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1004 |
method_name = "belongs_to_counter_cache_after_create_for_#{reflection.name}".to_sym |
| |
1005 |
define_method(method_name) do |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1006 |
association = send(reflection.name) |
| |
1007 |
association.class.increment_counter(cache_column, send(reflection.primary_key_name)) unless association.nil? |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1008 |
end |
| |
1009 |
after_create method_name |
|
964b67dd
»
|
jamis |
2006-03-04 |
Make counter_cache work wit... |
1010 |
|
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1011 |
method_name = "belongs_to_counter_cache_before_destroy_for_#{reflection.name}".to_sym |
| |
1012 |
define_method(method_name) do |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1013 |
association = send(reflection.name) |
| |
1014 |
association.class.decrement_counter(cache_column, send(reflection.primary_key_name)) unless association.nil? |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1015 |
end |
| |
1016 |
before_destroy method_name |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1017 |
|
|
66d05f5e
»
|
technoweenie |
2007-09-30 |
Add attr_readonly to specif... |
1018 |
module_eval( |
|
24c2457a
»
|
technoweenie |
2007-10-05 |
Don't call attr_readonly on... |
1019 |
"#{reflection.class_name}.send(:attr_readonly,\"#{cache_column}\".intern) if defined?(#{reflection.class_name}) && #{reflection.class_name}.respond_to?(:attr_readonly)" |
|
66d05f5e
»
|
technoweenie |
2007-09-30 |
Add attr_readonly to specif... |
1020 |
) |
|
964b67dd
»
|
jamis |
2006-03-04 |
Make counter_cache work wit... |
1021 |
end |
|
16b129a6
»
|
jeremy |
2008-01-18 |
belongs_to supports :depend... |
1022 |
|
| |
1023 |
configure_dependency_for_belongs_to(reflection) |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
1024 |
end |
| |
1025 |
|
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1026 |
# Specifies a many-to-many relationship with another class. This associates two classes via an |
| |
1027 |
# intermediate join table. Unless the join table is explicitly specified as an option, it is |
| |
1028 |
# guessed using the lexical order of the class names. So a join between Developer and Project |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
1029 |
# will give the default join table name of "developers_projects" because "D" outranks "P". Note that this precedence |
| |
1030 |
# is calculated using the <tt><</tt> operator for String. This means that if the strings are of different lengths, |
|
56c55354
»
|
technoweenie |
2007-01-15 |
[DOC] clear up some ambigui... |
1031 |
# and the strings are equal when compared up to the shortest length, then the longer string is considered of higher |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
1032 |
# lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" |
| |
1033 |
# to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", |
| |
1034 |
# but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the |
| |
1035 |
# custom <tt>:join_table</tt> option if you need to. |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1036 |
# |
|
96d61055
»
|
lifo |
2009-02-05 |
Merge docrails along with t... |
1037 |
# The join table should not have a primary key or a model associated with it. You must manually generate the |
| |
1038 |
# join table with a migration such as this: |
| |
1039 |
# |
| |
1040 |
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration |
| |
1041 |
# def self.up |
| |
1042 |
# create_table :developers_projects, :id => false do |t| |
| |
1043 |
# t.integer :developer_id |
| |
1044 |
# t.integer :project_id |
| |
1045 |
# end |
| |
1046 |
# end |
| |
1047 |
# |
| |
1048 |
# def self.down |
| |
1049 |
# drop_table :developers_projects |
| |
1050 |
# end |
| |
1051 |
# end |
| |
1052 |
# |
|
53aa8da1
»
|
dhh |
2006-04-01 |
Fixed that records returned... |
1053 |
# Deprecated: Any additional fields added to the join table will be placed as attributes when pulling records out through |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
1054 |
# +has_and_belongs_to_many+ associations. Records returned from join tables with additional attributes will be marked as |
|
98dc5827
»
|
lifo |
2008-05-25 |
Merge docrails.  |
1055 |
# readonly (because we can't save changes to the additional attributes). It's strongly recommended that you upgrade any |
|
53aa8da1
»
|
dhh |
2006-04-01 |
Fixed that records returned... |
1056 |
# associations with attributes to a real join model (see introduction). |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1057 |
# |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
1058 |
# Adds the following methods for retrieval and query: |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1059 |
# |
| |
1060 |
# [collection(force_reload = false)] |
| |
1061 |
# Returns an array of all the associated objects. |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
1062 |
# An empty array is returned if none are found. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1063 |
# [collection<<(object, ...)] |
| |
1064 |
# Adds one or more objects to the collection by creating associations in the join table |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
1065 |
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method). |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1066 |
# [collection.delete(object, ...)] |
| |
1067 |
# Removes one or more objects from the collection by removing their associations from the join table. |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1068 |
# This does not destroy the objects. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1069 |
# [collection=objects] |
| |
1070 |
# Replaces the collection's content by deleting and adding objects as appropriate. |
| |
1071 |
# [collection_singular_ids] |
| |
1072 |
# Returns an array of the associated objects' ids. |
| |
1073 |
# [collection_singular_ids=ids] |
| |
1074 |
# Replace the collection by the objects identified by the primary keys in +ids+. |
| |
1075 |
# [collection.clear] |
| |
1076 |
# Removes every object from the collection. This does not destroy the objects. |
| |
1077 |
# [collection.empty?] |
| |
1078 |
# Returns +true+ if there are no associated objects. |
| |
1079 |
# [collection.size] |
| |
1080 |
# Returns the number of associated objects. |
| |
1081 |
# [collection.find(id)] |
| |
1082 |
# Finds an associated object responding to the +id+ and that |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
1083 |
# meets the condition that it has to be associated with this object. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1084 |
# Uses the same rules as ActiveRecord::Base.find. |
|
c3f53f41
»
|
lifo |
2008-12-19 |
Merge docrails |
1085 |
# [collection.exists?(...)] |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1086 |
# Checks whether an associated object with the given conditions exists. |
| |
1087 |
# Uses the same rules as ActiveRecord::Base.exists?. |
| |
1088 |
# [collection.build(attributes = {})] |
| |
1089 |
# Returns a new object of the collection type that has been instantiated |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
1090 |
# with +attributes+ and linked to this object through the join table, but has not yet been saved. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1091 |
# [collection.create(attributes = {})] |
| |
1092 |
# Returns a new object of the collection type that has been instantiated |
|
18a3333a
»
|
NZKoz |
2007-08-28 |
Formatting, grammar and spe... |
1093 |
# with +attributes+, linked to this object through the join table, and that has already been saved (if it passed the validation). |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1094 |
# |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1095 |
# (+collection+ is replaced with the symbol passed as the first argument, so |
| |
1096 |
# <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.) |
| |
1097 |
# |
| |
1098 |
# === Example |
| |
1099 |
# |
| |
1100 |
# A Developer class declares <tt>has_and_belongs_to_many :projects</tt>, which will add: |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1101 |
# * <tt>Developer#projects</tt> |
| |
1102 |
# * <tt>Developer#projects<<</tt> |
| |
1103 |
# * <tt>Developer#projects.delete</tt> |
|
bfe6a759
»
|
dhh |
2005-06-15 |
Added actual database-chang... |
1104 |
# * <tt>Developer#projects=</tt> |
|
cb0837a2
»
|
dhh |
2006-10-08 |
Doc fixes (closes #6325) |
1105 |
# * <tt>Developer#project_ids</tt> |
|
bfe6a759
»
|
dhh |
2005-06-15 |
Added actual database-chang... |
1106 |
# * <tt>Developer#project_ids=</tt> |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1107 |
# * <tt>Developer#projects.clear</tt> |
| |
1108 |
# * <tt>Developer#projects.empty?</tt> |
| |
1109 |
# * <tt>Developer#projects.size</tt> |
| |
1110 |
# * <tt>Developer#projects.find(id)</tt> |
|
c3f53f41
»
|
lifo |
2008-12-19 |
Merge docrails |
1111 |
# * <tt>Developer#clients.exists?(...)</tt> |
|
06075a9e
»
|
technoweenie |
2006-05-28 |
Fix the has_and_belongs_to_... |
1112 |
# * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("project_id" => id)</tt>) |
| |
1113 |
# * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("project_id" => id); c.save; c</tt>) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1114 |
# The declaration may include an options hash to specialize the behavior of the association. |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1115 |
# |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1116 |
# === Options |
| |
1117 |
# |
| |
1118 |
# [:class_name] |
| |
1119 |
# Specify the class name of the association. Use it only if that name can't be inferred |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1120 |
# from the association name. So <tt>has_and_belongs_to_many :projects</tt> will by default be linked to the |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
1121 |
# Project class, but if the real class name is SuperProject, you'll have to specify it with this option. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1122 |
# [:join_table] |
| |
1123 |
# Specify the name of the join table if the default based on lexical order isn't what you want. |
| |
1124 |
# <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method |
| |
1125 |
# MUST be declared underneath any +has_and_belongs_to_many+ declaration in order to work. |
| |
1126 |
# [:foreign_key] |
| |
1127 |
# Specify the foreign key used for the association. By default this is guessed to be the name |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
1128 |
# of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_and_belongs_to_many+ association |
|
886124e6
»
|
lifo |
2009-02-01 |
Merge docrails |
1129 |
# to Project will use "person_id" as the default <tt>:foreign_key</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1130 |
# [:association_foreign_key] |
|
886124e6
»
|
lifo |
2009-02-01 |
Merge docrails |
1131 |
# Specify the foreign key used for the association on the receiving side of the association. |
| |
1132 |
# By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed. |
| |
1133 |
# So if a Person class makes a +has_and_belongs_to_many+ association to Project, |
| |
1134 |
# the association will use "project_id" as the default <tt>:association_foreign_key</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1135 |
# [:conditions] |
| |
1136 |
# Specify the conditions that the associated object must meet in order to be included as a +WHERE+ |
|
c23c9bd1
»
|
technoweenie |
2008-03-21 |
Allow association scoping f... |
1137 |
# SQL fragment, such as <tt>authorized = 1</tt>. Record creations from the association are scoped if a hash is used. |
| |
1138 |
# <tt>has_many :posts, :conditions => {:published => true}</tt> will create published posts with <tt>@blog.posts.create</tt> |
| |
1139 |
# or <tt>@blog.posts.build</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1140 |
# [:order] |
| |
1141 |
# Specify the order in which the associated objects are returned as an <tt>ORDER BY</tt> SQL fragment, |
|
7143d801
»
|
Marcel Molina |
2007-11-07 |
Smattering of grammatical f... |
1142 |
# such as <tt>last_name, first_name DESC</tt> |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1143 |
# [:uniq] |
| |
1144 |
# If true, duplicate associated objects will be ignored by accessors and query methods. |
| |
1145 |
# [:finder_sql] |
| |
1146 |
# Overwrite the default generated SQL statement used to fetch the association with a manual statement |
|
44af2efa
»
|
ernie |
2008-08-28 |
Refactored AssociationColle... |
1147 |
# [:counter_sql] |
| |
1148 |
# Specify a complete SQL statement to fetch the size of the association. If <tt>:finder_sql</tt> is |
| |
1149 |
# specified but not <tt>:counter_sql</tt>, <tt>:counter_sql</tt> will be generated by replacing <tt>SELECT ... FROM</tt> with <tt>SELECT COUNT(*) FROM</tt>. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1150 |
# [:delete_sql] |
| |
1151 |
# Overwrite the default generated SQL statement used to remove links between the associated |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
1152 |
# classes with a manual statement. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1153 |
# [:insert_sql] |
| |
1154 |
# Overwrite the default generated SQL statement used to add links between the associated classes |
|
dc4eec11
»
|
lifo |
2008-05-09 |
Merge docrails: |
1155 |
# with a manual statement. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1156 |
# [:extend] |
| |
1157 |
# Anonymous module for extending the proxy, see "Association extensions". |
| |
1158 |
# [:include] |
| |
1159 |
# Specify second-order associations that should be eager loaded when the collection is loaded. |
| |
1160 |
# [:group] |
| |
1161 |
# An attribute name by which the result should be grouped. Uses the <tt>GROUP BY</tt> SQL-clause. |
|
97403ad5
»
|
miloops |
2008-11-21 |
Add :having option to find,... |
1162 |
# [:having] |
| |
1163 |
# Combined with +:group+ this can be used to filter the records that a <tt>GROUP BY</tt> returns. Uses the <tt>HAVING</tt> SQL-clause. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1164 |
# [:limit] |
| |
1165 |
# An integer determining the limit on the number of rows that should be returned. |
| |
1166 |
# [:offset] |
| |
1167 |
# An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows. |
| |
1168 |
# [:select] |
| |
1169 |
# By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join |
|
8d0b4fa3
»
|
josevalim |
2008-05-23 |
Added :select option to has... |
1170 |
# but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error. |
|
6e754551
»
|
lifo |
2008-07-28 |
Merge docrails changes |
1171 |
# [:readonly] |
| |
1172 |
# If true, all the associated objects are readonly through the association. |
| |
1173 |
# [:validate] |
| |
1174 |
# If false, don't validate the associated objects when saving the parent object. +true+ by default. |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1175 |
# [:autosave] |
| |
1176 |
# If true, always save any loaded members and destroy members marked for destruction, when saving the parent object. Off by default. |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1177 |
# |
| |
1178 |
# Option examples: |
| |
1179 |
# has_and_belongs_to_many :projects |
|
49c801b7
»
|
dhh |
2005-11-06 |
Added :include as an option... |
1180 |
# has_and_belongs_to_many :projects, :include => [ :milestones, :manager ] |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1181 |
# has_and_belongs_to_many :nations, :class_name => "Country" |
| |
1182 |
# has_and_belongs_to_many :categories, :join_table => "prods_cats" |
|
dfa78663
»
|
jeremy |
2008-02-12 |
Introduce the :readonly opt... |
1183 |
# has_and_belongs_to_many :categories, :readonly => true |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1184 |
# has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql => |
|
190e0464
»
|
dhh |
2005-05-19 |
Fixed that :delete_sql in h... |
1185 |
# 'DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}' |
|
c8dd66fd
»
|
dhh |
2005-11-06 |
Made association extensions... |
1186 |
def has_and_belongs_to_many(association_id, options = {}, &extension) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1187 |
reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension) |
| |
1188 |
collection_accessor_methods(reflection, HasAndBelongsToManyAssociation) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1189 |
|
|
35b4bdcf
»
|
jeremy |
2005-11-08 |
Destroy associated has_and_... |
1190 |
# Don't use a before_destroy callback since users' before_destroy |
| |
1191 |
# callbacks will be executed after the association is wiped out. |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1192 |
old_method = "destroy_without_habtm_shim_for_#{reflection.name}" |
|
88f951a5
»
|
jeremy |
2007-10-27 |
Allow association redefinit... |
1193 |
class_eval <<-end_eval unless method_defined?(old_method) |
|
a2270ef2
»
|
fxn |
2008-12-28 |
Inline code comments for cl...  |
1194 |
alias_method :#{old_method}, :destroy_without_callbacks # alias_method :destroy_without_habtm_shim_for_posts, :destroy_without_callbacks |
| |
1195 |
def destroy_without_callbacks # def destroy_without_callbacks |
| |
1196 |
#{reflection.name}.clear # posts.clear |
| |
1197 |
#{old_method} # destroy_without_habtm_shim_for_posts |
| |
1198 |
end # end |
|
35b4bdcf
»
|
jeremy |
2005-11-08 |
Destroy associated has_and_... |
1199 |
end_eval |
| |
1200 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1201 |
add_association_callbacks(reflection.name, options) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1202 |
end |
| |
1203 |
|
| |
1204 |
private |
|
6ef35461
»
|
lifo |
2008-09-03 |
Merge docrails |
1205 |
# Generates a join table name from two provided table names. |
| |
1206 |
# The names in the join table namesme end up in lexicographic order. |
| |
1207 |
# |
| |
1208 |
# join_table_name("members", "clubs") # => "clubs_members" |
| |
1209 |
# join_table_name("members", "special_clubs") # => "members_special_clubs" |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1210 |
def join_table_name(first_table_name, second_table_name) |
| |
1211 |
if first_table_name < second_table_name |
| |
1212 |
join_table = "#{first_table_name}_#{second_table_name}" |
| |
1213 |
else |
| |
1214 |
join_table = "#{second_table_name}_#{first_table_name}" |
| |
1215 |
end |
| |
1216 |
|
| |
1217 |
table_name_prefix + join_table + table_name_suffix |
| |
1218 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1219 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1220 |
def association_accessor_methods(reflection, association_proxy_class) |
| |
1221 |
define_method(reflection.name) do |*params| |
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
1222 |
force_reload = params.first unless params.empty? |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1223 |
association = association_instance_get(reflection.name) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1224 |
|
|
cb45ee34
»
|
NZKoz |
2008-10-10 |
Remove the functionality in... |
1225 |
if association.nil? || force_reload |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1226 |
association = association_proxy_class.new(self, reflection) |
|
bce0e149
»
|
dhh |
2005-01-18 |
Fixed that the belongs_to a... |
1227 |
retval = association.reload |
|
94a13091
»
|
technoweenie |
2006-08-08 |
Cache nil results for has_o... |
1228 |
if retval.nil? and association_proxy_class == BelongsToAssociation |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1229 |
association_instance_set(reflection.name, nil) |
|
bce0e149
»
|
dhh |
2005-01-18 |
Fixed that the belongs_to a... |
1230 |
return nil |
| |
1231 |
end |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1232 |
association_instance_set(reflection.name, association) |
|
bce0e149
»
|
dhh |
2005-01-18 |
Fixed that the belongs_to a... |
1233 |
end |
|
94a13091
»
|
technoweenie |
2006-08-08 |
Cache nil results for has_o... |
1234 |
|
| |
1235 |
association.target.nil? ? nil : association |
|
bce0e149
»
|
dhh |
2005-01-18 |
Fixed that the belongs_to a... |
1236 |
end |
| |
1237 |
|
|
4c050554
»
|
willbryant |
2008-09-26 |
explicitly including child ... |
1238 |
define_method("loaded_#{reflection.name}?") do |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1239 |
association = association_instance_get(reflection.name) |
|
4c050554
»
|
willbryant |
2008-09-26 |
explicitly including child ... |
1240 |
association && association.loaded? |
| |
1241 |
end |
| |
1242 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1243 |
define_method("#{reflection.name}=") do |new_value| |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1244 |
association = association_instance_get(reflection.name) |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1245 |
|
|
4afd6c9f
»
|
jeremy |
2007-05-21 |
belongs_to assignment creat... |
1246 |
if association.nil? || association.target != new_value |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1247 |
association = association_proxy_class.new(self, reflection) |
|
bce0e149
»
|
dhh |
2005-01-18 |
Fixed that the belongs_to a... |
1248 |
end |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1249 |
|
|
273b21fa
»
|
technoweenie |
2008-03-21 |
Add has_one :through suppor... |
1250 |
if association_proxy_class == HasOneThroughAssociation |
| |
1251 |
association.create_through_record(new_value) |
| |
1252 |
self.send(reflection.name, new_value) |
| |
1253 |
else |
|
9dbde4f5
»
|
pivotal |
2008-08-26 |
Fix two has_one :through er... |
1254 |
association.replace(new_value) |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1255 |
association_instance_set(reflection.name, new_value.nil? ? nil : association) |
|
273b21fa
»
|
technoweenie |
2008-03-21 |
Add has_one :through suppor... |
1256 |
end |
|
bce0e149
»
|
dhh |
2005-01-18 |
Fixed that the belongs_to a... |
1257 |
end |
|
f8783abf
»
|
dhh |
2005-04-03 |
Made eager loading work eve... |
1258 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1259 |
define_method("set_#{reflection.name}_target") do |target| |
|
18057d2f
»
|
jeremy |
2006-08-17 |
Cache nil results for :incl... |
1260 |
return if target.nil? and association_proxy_class == BelongsToAssociation |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1261 |
association = association_proxy_class.new(self, reflection) |
|
f8783abf
»
|
dhh |
2005-04-03 |
Made eager loading work eve... |
1262 |
association.target = target |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1263 |
association_instance_set(reflection.name, association) |
|
f8783abf
»
|
dhh |
2005-04-03 |
Made eager loading work eve... |
1264 |
end |
|
bce0e149
»
|
dhh |
2005-01-18 |
Fixed that the belongs_to a... |
1265 |
end |
| |
1266 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1267 |
def collection_reader_method(reflection, association_proxy_class) |
| |
1268 |
define_method(reflection.name) do |*params| |
|
bce0e149
»
|
dhh |
2005-01-18 |
Fixed that the belongs_to a... |
1269 |
force_reload = params.first unless params.empty? |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1270 |
association = association_instance_get(reflection.name) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1271 |
|
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1272 |
unless association |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1273 |
association = association_proxy_class.new(self, reflection) |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1274 |
association_instance_set(reflection.name, association) |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1275 |
end |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1276 |
|
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
1277 |
association.reload if force_reload |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1278 |
|
|
823554ea
»
|
dhh |
2005-01-15 |
Added support for associati... |
1279 |
association |
| |
1280 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1281 |
|
| |
1282 |
define_method("#{reflection.name.to_s.singularize}_ids") do |
|
838cb1aa
»
|
jeremy |
2008-10-23 |
Skip collection ids reader ... |
1283 |
if send(reflection.name).loaded? || reflection.options[:finder_sql] |
|
b163d83b
»
|
miloops |
2008-08-30 |
Performance: Better query f... |
1284 |
send(reflection.name).map(&:id) |
| |
1285 |
else |
|
6183e55f
»
|
miloops |
2008-08-30 |
Use reflection primary_key ... |
1286 |
send(reflection.name).all(:select => "#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").map(&:id) |
|
b163d83b
»
|
miloops |
2008-08-30 |
Performance: Better query f... |
1287 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1288 |
end |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1289 |
end |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1290 |
|
|
b5b16a80
»
|
jeremy |
2007-06-27 |
Define collection singular ... |
1291 |
def collection_accessor_methods(reflection, association_proxy_class, writer = true) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1292 |
collection_reader_method(reflection, association_proxy_class) |
| |
1293 |
|
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1294 |
if writer |
| |
1295 |
define_method("#{reflection.name}=") do |new_value| |
| |
1296 |
# Loads proxy class instance (defined in collection_reader_method) if not already loaded |
| |
1297 |
association = send(reflection.name) |
| |
1298 |
association.replace(new_value) |
| |
1299 |
association |
| |
1300 |
end |
|
bfe6a759
»
|
dhh |
2005-06-15 |
Added actual database-chang... |
1301 |
|
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1302 |
define_method("#{reflection.name.to_s.singularize}_ids=") do |new_value| |
| |
1303 |
ids = (new_value || []).reject { |nid| nid.blank? } |
| |
1304 |
send("#{reflection.name}=", reflection.class_name.constantize.find(ids)) |
| |
1305 |
end |
|
0092d0ac
»
|
jeremy |
2006-10-01 |
Association collections hav... |
1306 |
end |
|
db045dbb
»
|
dhh |
2004-11-23 |
Initial |
1307 |
end |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1308 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1309 |
def association_constructor_method(constructor, reflection, association_proxy_class) |
| |
1310 |
define_method("#{constructor}_#{reflection.name}") do |*params| |
|
2bdaff4a
»
|
dhh |
2005-06-06 |
Added a second parameter to... |
1311 |
attributees = params.first unless params.empty? |
| |
1312 |
replace_existing = params[1].nil? ? true : params[1] |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1313 |
association = association_instance_get(reflection.name) |
|
3b9e90a4
»
|
dhh |
2005-04-11 |
Moved build_association and... |
1314 |
|
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1315 |
unless association |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1316 |
association = association_proxy_class.new(self, reflection) |
|
ec8f0458
»
|
alloy |
2009-01-31 |
Add support for nested obje...  |
1317 |
association_instance_set(reflection.name, association) |
|
3b9e90a4
»
|
dhh |
2005-04-11 |
Moved build_association and... |
1318 |
end |
| |
1319 |
|
|
bfe6a759
»
|
dhh |
2005-06-15 |
Added actual database-chang... |
1320 |
if association_proxy_class == HasOneAssociation |
| |
1321 |
association.send(constructor, attributees, replace_existing) |
| |
1322 |
else |
| |
1323 |
association.send(constructor, attributees) |
| |
1324 |
end |
|
3b9e90a4
»
|
dhh |
2005-04-11 |
Moved build_association and... |
1325 |
end |
| |
1326 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1327 |
|
|
abc895b8
»
|
dhh |
2005-04-03 |
Added new Base.find API and... |
1328 |
def find_with_associations(options = {}) |
|
31d8169e
»
|
technoweenie |
2006-04-05 |
Fixed that loading includin... |
1329 |
catch :invalid_query do |
|
37adea6f
»
|
dhh |
2007-11-07 |
Address shortcomings of cha... |
1330 |
join_dependency = JoinDependency.new(self, merge_includes(scope(:find, :include), options[:include]), options[:joins]) |
|
31d8169e
»
|
technoweenie |
2006-04-05 |
Fixed that loading includin... |
1331 |
rows = select_all_rows(options, join_dependency) |
| |
1332 |
return join_dependency.instantiate(rows) |
| |
1333 |
end |
| |
1334 |
[] |
|
3a7be80f
»
|
dhh |
2006-03-15 |
Change LEFT OUTER JOIN auth... |
1335 |
end |
|
6f344000
»
|
dhh |
2005-04-19 |
Fixed order of loading in e... |
1336 |
|
|
72b772ae
»
|
Hongli Lai (Phusion) |
2008-09-21 |
Refactor configure_dependen... |
1337 |
# Creates before_destroy callback methods that nullify, delete or destroy |
| |
1338 |
# has_many associated objects, according to the defined :dependent rule. |
| |
1339 |
# |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1340 |
# See HasManyAssociation#delete_records. Dependent associations |
| |
1341 |
# delete children, otherwise foreign key is set to NULL. |
|
72b772ae
»
|
Hongli Lai (Phusion) |
2008-09-21 |
Refactor configure_dependen... |
1342 |
# |
| |
1343 |
# The +extra_conditions+ parameter, which is not used within the main |
| |
1344 |
# Active Record codebase, is meant to allow plugins to define extra |
| |
1345 |
# finder conditions. |
| |
1346 |
def configure_dependency_for_has_many(reflection, extra_conditions = nil) |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1347 |
if reflection.options.include?(:dependent) |
| |
1348 |
# Add polymorphic type if the :as option is present |
| |
1349 |
dependent_conditions = [] |
| |
1350 |
dependent_conditions << "#{reflection.primary_key_name} = \#{record.quoted_id}" |
| |
1351 |
dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as] |
| |
1352 |
dependent_conditions << sanitize_sql(reflection.options[:conditions]) if reflection.options[:conditions] |
|
72b772ae
»
|
Hongli Lai (Phusion) |
2008-09-21 |
Refactor configure_dependen... |
1353 |
dependent_conditions << extra_conditions if extra_conditions |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1354 |
dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ") |
|
b17b9371
»
|
fcheung |
2008-12-21 |
Fix configure_dependency_fo... |
1355 |
dependent_conditions = dependent_conditions.gsub('@', '\@') |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1356 |
case reflection.options[:dependent] |
| |
1357 |
when :destroy |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1358 |
method_name = "has_many_dependent_destroy_for_#{reflection.name}".to_sym |
| |
1359 |
define_method(method_name) do |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1360 |
send(reflection.name).each { |o| o.destroy } |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1361 |
end |
| |
1362 |
before_destroy method_name |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1363 |
when :delete_all |
|
72b772ae
»
|
Hongli Lai (Phusion) |
2008-09-21 |
Refactor configure_dependen... |
1364 |
module_eval %Q{ |
|
a2270ef2
»
|
fxn |
2008-12-28 |
Inline code comments for cl...  |
1365 |
before_destroy do |record| # before_destroy do |record| |
| |
1366 |
delete_all_has_many_dependencies(record, # delete_all_has_many_dependencies(record, |
| |
1367 |
"#{reflection.name}", # "posts", |
| |
1368 |
#{reflection.class_name}, # Post, |
| |
1369 |
%@#{dependent_conditions}@) # %@...@) # this is a string literal like %(...) |
| |
1370 |
end # end |
|
72b772ae
»
|
Hongli Lai (Phusion) |
2008-09-21 |
Refactor configure_dependen... |
1371 |
} |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1372 |
when :nullify |
|
72b772ae
»
|
Hongli Lai (Phusion) |
2008-09-21 |
Refactor configure_dependen... |
1373 |
module_eval %Q{ |
|
a2270ef2
»
|
fxn |
2008-12-28 |
Inline code comments for cl...  |
1374 |
before_destroy do |record| # before_destroy do |record| |
| |
1375 |
nullify_has_many_dependencies(record, # nullify_has_many_dependencies(record, |
| |
1376 |
"#{reflection.name}", # "posts", |
| |
1377 |
#{reflection.class_name}, # Post, |
| |
1378 |
"#{reflection.primary_key_name}", # "user_id", |
| |
1379 |
%@#{dependent_conditions}@) # %@...@) # this is a string literal like %(...) |
| |
1380 |
end # end |
|
72b772ae
»
|
Hongli Lai (Phusion) |
2008-09-21 |
Refactor configure_dependen... |
1381 |
} |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1382 |
else |
| |
1383 |
raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, or :nullify (#{reflection.options[:dependent].inspect})" |
| |
1384 |
end |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1385 |
end |
| |
1386 |
end |
|
3f1acf49
»
|
jeremy |
2006-09-15 |
Deprecation tests. Remove w... |
1387 |
|
|
a2932784
»
|
lifo |
2008-10-05 |
Merge docrails |
1388 |
# Creates before_destroy callback methods that nullify, delete or destroy |
| |
1389 |
# has_one associated objects, according to the defined :dependent rule. |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1390 |
def configure_dependency_for_has_one(reflection) |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1391 |
if reflection.options.include?(:dependent) |
| |
1392 |
case reflection.options[:dependent] |
| |
1393 |
when :destroy |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1394 |
method_name = "has_one_dependent_destroy_for_#{reflection.name}".to_sym |
| |
1395 |
define_method(method_name) do |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1396 |
association = send(reflection.name) |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1397 |
association.destroy unless association.nil? |
| |
1398 |
end |
| |
1399 |
before_destroy method_name |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1400 |
when :delete |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1401 |
method_name = "has_one_dependent_delete_for_#{reflection.name}".to_sym |
| |
1402 |
define_method(method_name) do |
|
a2932784
»
|
lifo |
2008-10-05 |
Merge docrails |
1403 |
# Retrieve the associated object and delete it. The retrieval |
| |
1404 |
# is necessary because there may be multiple associated objects |
| |
1405 |
# with foreign keys pointing to this object, and we only want |
| |
1406 |
# to delete the correct one, not all of them. |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1407 |
association = send(reflection.name) |
|
46939a9b
»
|
Hongli Lai (Phusion |
2008-09-21 |
Add Model#delete instance m...  |
1408 |
association.delete unless association.nil? |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1409 |
end |
| |
1410 |
before_destroy method_name |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1411 |
when :nullify |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1412 |
method_name = "has_one_dependent_nullify_for_#{reflection.name}".to_sym |
| |
1413 |
define_method(method_name) do |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1414 |
association = send(reflection.name) |
| |
1415 |
association.update_attribute(reflection.primary_key_name, nil) unless association.nil? |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1416 |
end |
| |
1417 |
before_destroy method_name |
|
aa04635d
»
|
jeremy |
2007-10-08 |
Update :dependent docs and ... |
1418 |
else |
| |
1419 |
raise ArgumentError, "The :dependent option expects either :destroy, :delete or :nullify (#{reflection.options[:dependent].inspect})" |
| |
1420 |
end |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1421 |
end |
| |
1422 |
end |
| |
1423 |
|
|
16b129a6
»
|
jeremy |
2008-01-18 |
belongs_to supports :depend... |
1424 |
def configure_dependency_for_belongs_to(reflection) |
| |
1425 |
if reflection.options.include?(:dependent) |
| |
1426 |
case reflection.options[:dependent] |
| |
1427 |
when :destroy |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1428 |
method_name = "belongs_to_dependent_destroy_for_#{reflection.name}".to_sym |
| |
1429 |
define_method(method_name) do |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1430 |
association = send(reflection.name) |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1431 |
association.destroy unless association.nil? |
| |
1432 |
end |
|
0e92f670
»
|
bvandenbos |
2009-01-05 |
Make belongs_to :dependent ... |
1433 |
after_destroy method_name |
|
16b129a6
»
|
jeremy |
2008-01-18 |
belongs_to supports :depend... |
1434 |
when :delete |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1435 |
method_name = "belongs_to_dependent_delete_for_#{reflection.name}".to_sym |
| |
1436 |
define_method(method_name) do |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1437 |
association = send(reflection.name) |
|
46939a9b
»
|
Hongli Lai (Phusion |
2008-09-21 |
Add Model#delete instance m...  |
1438 |
association.delete unless association.nil? |
|
de048b10
»
|
technoweenie |
2008-02-13 |
Improve associations perfor... |
1439 |
end |
|
0e92f670
»
|
bvandenbos |
2009-01-05 |
Make belongs_to :dependent ... |
1440 |
after_destroy method_name |
|
16b129a6
»
|
jeremy |
2008-01-18 |
belongs_to supports :depend... |
1441 |
else |
| |
1442 |
raise ArgumentError, "The :dependent option expects either :destroy or :delete (#{reflection.options[:dependent].inspect})" |
| |
1443 |
end |
| |
1444 |
end |
| |
1445 |
end |
| |
1446 |
|
|
72b772ae
»
|
Hongli Lai (Phusion) |
2008-09-21 |
Refactor configure_dependen... |
1447 |
def delete_all_has_many_dependencies(record, reflection_name, association_class, dependent_conditions) |
| |
1448 |
association_class.delete_all(dependent_conditions) |
| |
1449 |
end |
| |
1450 |
|
| |
1451 |
def nullify_has_many_dependencies(record, reflection_name, association_class, primary_key_name, dependent_conditions) |
| |
1452 |
association_class.update_all("#{primary_key_name} = NULL", dependent_conditions) |
| |
1453 |
end |
| |
1454 |
|
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1455 |
mattr_accessor :valid_keys_for_has_many_association |
| |
1456 |
@@valid_keys_for_has_many_association = [ |
| |
1457 |
:class_name, :table_name, :foreign_key, :primary_key, |
| |
1458 |
:dependent, |
|
97403ad5
»
|
miloops |
2008-11-21 |
Add :having option to find,... |
1459 |
:select, :conditions, :include, :order, :group, :having, :limit, :offset, |
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1460 |
:as, :through, :source, :source_type, |
| |
1461 |
:uniq, |
| |
1462 |
:finder_sql, :counter_sql, |
| |
1463 |
:before_add, :after_add, :before_remove, :after_remove, |
| |
1464 |
:extend, :readonly, |
|
9994f0d9
»
|
lifo |
2008-09-10 |
Revert "Add :accessible opt...  |
1465 |
:validate |
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1466 |
] |
| |
1467 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1468 |
def create_has_many_reflection(association_id, options, &extension) |
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1469 |
options.assert_valid_keys(valid_keys_for_has_many_association) |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1470 |
options[:extend] = create_extension_modules(association_id, extension, options[:extend]) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1471 |
|
|
8203a2af
»
|
dhh |
2006-02-26 |
Dont require association cl... |
1472 |
create_reflection(:has_many, association_id, options, self) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1473 |
end |
| |
1474 |
|
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1475 |
mattr_accessor :valid_keys_for_has_one_association |
| |
1476 |
@@valid_keys_for_has_one_association = [ |
| |
1477 |
:class_name, :foreign_key, :remote, :select, :conditions, :order, |
| |
1478 |
:include, :dependent, :counter_cache, :extend, :as, :readonly, |
|
9994f0d9
»
|
lifo |
2008-09-10 |
Revert "Add :accessible opt...  |
1479 |
:validate, :primary_key |
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1480 |
] |
| |
1481 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1482 |
def create_has_one_reflection(association_id, options) |
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1483 |
options.assert_valid_keys(valid_keys_for_has_one_association) |
|
8203a2af
»
|
dhh |
2006-02-26 |
Dont require association cl... |
1484 |
create_reflection(:has_one, association_id, options, self) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1485 |
end |
|
ba3ecf53
»
|
clemens |
2008-09-02 |
Some performance goodness f... |
1486 |
|
|
273b21fa
»
|
technoweenie |
2008-03-21 |
Add has_one :through suppor... |
1487 |
def create_has_one_through_reflection(association_id, options) |
| |
1488 |
options.assert_valid_keys( |
|
7f140bbd
»
|
DefV |
2008-06-11 |
Add :validate option to ass... |
1489 |
:class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :through, :source, :source_type, :validate |
|
273b21fa
»
|
technoweenie |
2008-03-21 |
Add has_one :through suppor... |
1490 |
) |
| |
1491 |
create_reflection(:has_one, association_id, options, self) |
| |
1492 |
end |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1493 |
|
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1494 |
mattr_accessor :valid_keys_for_belongs_to_association |
| |
1495 |
@@valid_keys_for_belongs_to_association = [ |
| |
1496 |
:class_name, :foreign_key, :foreign_type, :remote, :select, :conditions, |
| |
1497 |
:include, :dependent, :counter_cache, :extend, :polymorphic, :readonly, |
|
9994f0d9
»
|
lifo |
2008-09-10 |
Revert "Add :accessible opt...  |
1498 |
:validate |
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1499 |
] |
| |
1500 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1501 |
def create_belongs_to_reflection(association_id, options) |
|
16929404
»
|
Hongli Lai (Phusion) |
2008-09-06 |
Make the options that has_m... |
1502 |
options.assert_valid_keys(valid_keys_for_belongs_to_association) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1503 |
reflection = create_reflection(:belongs_to, association_id, options, self) |
| |
1504 |
|
| |
1505 |
if options[:polymorphic] |
| |
1506 |
reflection.options[:foreign_type] ||= reflection.class_name.underscore + "_type" |
| |
1507 |
end |
| |
1508 |
|
| |
1509 |
reflection |
| |
1510 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1511 |
|
|
5229fc4c
»
|
jodosha |
2008-10-31 |
Make sure habtm use class v... |
1512 |
mattr_accessor :valid_keys_for_has_and_belongs_to_many_association |
| |
1513 |
@@valid_keys_for_has_and_belongs_to_many_association = [ |
| |
1514 |
:class_name, :table_name, :join_table, :foreign_key, :association_foreign_key, |
|
97403ad5
»
|
miloops |
2008-11-21 |
Add :having option to find,... |
1515 |
:select, :conditions, :include, :order, :group, :having, :limit, :offset, |
|
5229fc4c
»
|
jodosha |
2008-10-31 |
Make sure habtm use class v... |
1516 |
:uniq, |
|
26978e3c
»
|
tekin |
2008-11-06 |
Added :counter_sql as a val... |
1517 |
:finder_sql, :counter_sql, :delete_sql, :insert_sql, |
|
5229fc4c
»
|
jodosha |
2008-10-31 |
Make sure habtm use class v... |
1518 |
:before_add, :after_add, :before_remove, :after_remove, |
| |
1519 |
:extend, :readonly, |
| |
1520 |
:validate |
| |
1521 |
] |
| |
1522 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1523 |
def create_has_and_belongs_to_many_reflection(association_id, options, &extension) |
|
5229fc4c
»
|
jodosha |
2008-10-31 |
Make sure habtm use class v... |
1524 |
options.assert_valid_keys(valid_keys_for_has_and_belongs_to_many_association) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1525 |
|
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1526 |
options[:extend] = create_extension_modules(association_id, extension, options[:extend]) |
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1527 |
|
| |
1528 |
reflection = create_reflection(:has_and_belongs_to_many, association_id, options, self) |
| |
1529 |
|
| |
1530 |
reflection.options[:join_table] ||= join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(reflection.class_name)) |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1531 |
|
|
6abda696
»
|
dhh |
2005-12-02 |
Added preliminary support f... |
1532 |
reflection |
| |
1533 |
end |
| |
1534 |
|
|
49d0f0cb
»
|
dhh |
2005-04-18 |
Speeded up eager loading a ... |
1535 |
def reflect_on_included_associations(associations) |
|
251a5d45
»
|
seckar |
2005-09-18 |
Fix eager loading error mes... |
1536 |
[ associations ].flatten.collect { |association| reflect_on_association(association.to_s.intern) } |
|
49d0f0cb
»
|
dhh |
2005-04-18 |
Speeded up eager loading a ... |
1537 |
end |
| |
1538 |
|
|
5b9b904f
»
|
dhh |
2005-07-10 |
Added support for limit and... |
1539 |
def guard_against_unlimitable_reflections(reflections, options) |
| |
1540 |
if (options[:offset] || options[:limit]) && !using_limitable_reflections?(reflections) |
| |
1541 |
raise( |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1542 |
ConfigurationError, |
|
5b9b904f
»
|
dhh |
2005-07-10 |
Added support for limit and... |
1543 |
"You can not use offset and limit together with has_many or has_and_belongs_to_many associations" |
| |
1544 |
) |
| |
1545 |
end |
| |
1546 |
end |
| |
1547 |
|
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1548 |
def select_all_rows(options, join_dependency) |
|
49d0f0cb
»
|
dhh |
2005-04-18 |
Speeded up eager loading a ... |
1549 |
connection.select_all( |
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1550 |
construct_finder_sql_with_included_associations(options, join_dependency), |
|
49d0f0cb
»
|
dhh |
2005-04-18 |
Speeded up eager loading a ... |
1551 |
"#{name} Load Including Associations" |
| |
1552 |
) |
| |
1553 |
end |
|
057cf491
»
|
dhh |
2005-04-10 |
Added support for has_and_b... |
1554 |
|
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1555 |
def construct_finder_sql_with_included_associations(options, join_dependency) |
|
c9c18520
»
|
dhh |
2006-03-27 |
Making ActiveRecord faster ... |
1556 |
scope = scope(:find) |
|
a5fded3e
»
|
dhh |
2007-12-04 |
Fix that options[:from] tab... |
1557 |
sql = "SELECT #{column_aliases(join_dependency)} FROM #{(scope && scope[:from]) || options[:from] || quoted_table_name} " |
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1558 |
sql << join_dependency.join_associations.collect{|join| join.association_join }.join |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1559 |
|
|
db22c895
»
|
pixeltrix |
2008-08-28 |
Merge scoped :joins togethe... |
1560 |
add_joins!(sql, options[:joins], scope) |
|
c9c18520
»
|
dhh |
2006-03-27 |
Making ActiveRecord faster ... |
1561 |
add_conditions!(sql, options[:conditions], scope) |
|
d016d9a6
»
|
dhh |
2006-06-03 |
Fixed usage of :limit and w... |
1562 |
add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit]) |
|
851dd080
»
|
dhh |
2005-10-18 |
Added support for using lim... |
1563 |
|
|
97403ad5
»
|
miloops |
2008-11-21 |
Add :having option to find,... |
1564 |
add_group!(sql, options[:group], options[:having], scope) |
|
9d2da046
»
|
jeremy |
2006-11-09 |
Cache inheritance_column. C... |
1565 |
add_order!(sql, options[:order], scope) |
|
c9c18520
»
|
dhh |
2006-03-27 |
Making ActiveRecord faster ... |
1566 |
add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections) |
|
8dea60b0
»
|
jeremy |
2006-12-05 |
find supports :lock with :i... |
1567 |
add_lock!(sql, options, scope) |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1568 |
|
|
abc895b8
»
|
dhh |
2005-04-03 |
Added new Base.find API and... |
1569 |
return sanitize_sql(sql) |
| |
1570 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1571 |
|
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1572 |
def add_limited_ids_condition!(sql, options, join_dependency) |
| |
1573 |
unless (id_list = select_limited_ids_list(options, join_dependency)).empty? |
|
79823e0b
»
|
NZKoz |
2007-11-10 |
Ensure that column names ar... |
1574 |
sql << "#{condition_word(sql)} #{connection.quote_table_name table_name}.#{primary_key} IN (#{id_list}) " |
|
31d8169e
»
|
technoweenie |
2006-04-05 |
Fixed that loading includin... |
1575 |
else |
| |
1576 |
throw :invalid_query |
|
851dd080
»
|
dhh |
2005-10-18 |
Added support for using lim... |
1577 |
end |
| |
1578 |
end |
|
4965b1b9
»
|
jeremy |
2007-09-22 |
Correctly quote id list for... |
1579 |
|
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1580 |
def select_limited_ids_list(options, join_dependency) |
|
4965b1b9
»
|
jeremy |
2007-09-22 |
Correctly quote id list for... |
1581 |
pk = columns_hash[primary_key] |
| |
1582 |
|
|
5ea76fab
»
|
technoweenie |
2006-04-18 |
Associations#select_limited... |
1583 |
connection.select_all( |
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1584 |
construct_finder_sql_for_association_limiting(options, join_dependency), |
|
851dd080
»
|
dhh |
2005-10-18 |
Added support for using lim... |
1585 |
"#{name} Load IDs For Limited Eager Loading" |
|
4965b1b9
»
|
jeremy |
2007-09-22 |
Correctly quote id list for... |
1586 |
).collect { |row| connection.quote(row[primary_key], pk) }.join(", ") |
|
851dd080
»
|
dhh |
2005-10-18 |
Added support for using lim... |
1587 |
end |
|
c0bce43e
»
|
jeremy |
2006-11-10 |
Oracle: fix limited id sele... |
1588 |
|
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1589 |
def construct_finder_sql_for_association_limiting(options, join_dependency) |
|
e789b26e
»
|
technoweenie |
2006-10-13 |
fix select_limited_ids_list... |
1590 |
scope = scope(:find) |
|
4ca170fc
»
|
NZKoz |
2008-03-02 |
Improve performance on :inc... |
1591 |
|
| |
1592 |
# Only join tables referenced in order or conditions since this is particularly slow on the pre-query. |
| |
1593 |
tables_from_conditions = conditions_tables(options) |
| |
1594 |
tables_from_order = order_tables(options) |
| |
1595 |
all_tables = tables_from_conditions + tables_from_order |
|
8ded457b
»
|
jdevine |
2008-05-03 |
Added logic to associations... |
1596 |
distinct_join_associations = all_tables.uniq.map{|table| |
| |
1597 |
join_dependency.joins_for_table_name(table) |
| |
1598 |
}.flatten.compact.uniq |
| |
1599 |
|
|
8c91b767
»
|
tarmo |
2008-07-14 |
Fixed postgresql limited ea... |
1600 |
order = options[:order] |
| |
1601 |
if scoped_order = (scope && scope[:order]) |
| |
1602 |
order = order ? "#{order}, #{scoped_order}" : scoped_order |
| |
1603 |
end |
| |
1604 |
|
|
4ca170fc
»
|
NZKoz |
2008-03-02 |
Improve performance on :inc... |
1605 |
is_distinct = !options[:joins].blank? || include_eager_conditions?(options, tables_from_conditions) || include_eager_order?(options, tables_from_order) |
|
d49a5fcb
»
|
NZKoz |
2006-02-09 |
* Fix pagination problems w... |
1606 |
sql = "SELECT " |
|
e789b26e
»
|
technoweenie |
2006-10-13 |
fix select_limited_ids_list... |
1607 |
if is_distinct |
|
8c91b767
»
|
tarmo |
2008-07-14 |
Fixed postgresql limited ea... |
1608 |
sql << connection.distinct("#{connection.quote_table_name table_name}.#{primary_key}", order) |
|
e789b26e
»
|
technoweenie |
2006-10-13 |
fix select_limited_ids_list... |
1609 |
else |
| |
1610 |
sql << primary_key |
| |
1611 |
end |
|
79823e0b
»
|
NZKoz |
2007-11-10 |
Ensure that column names ar... |
1612 |
sql << " FROM #{connection.quote_table_name table_name} " |
|
c0bce43e
»
|
jeremy |
2006-11-10 |
Oracle: fix limited id sele... |
1613 |
|
|
e789b26e
»
|
technoweenie |
2006-10-13 |
fix select_limited_ids_list... |
1614 |
if is_distinct |
|
ce4a1bb8
»
|
chuyeow |
2008-06-25 |
Remove some Symbol#to_proc ...  |
1615 |
sql << distinct_join_associations.collect { |assoc| assoc.association_join }.join |
|
db22c895
»
|
pixeltrix |
2008-08-28 |
Merge scoped :joins togethe... |
1616 |
add_joins!(sql, options[:joins], scope) |
|
d49a5fcb
»
|
NZKoz |
2006-02-09 |
* Fix pagination problems w... |
1617 |
end |
|
c0bce43e
»
|
jeremy |
2006-11-10 |
Oracle: fix limited id sele... |
1618 |
|
|
c9c18520
»
|
dhh |
2006-03-27 |
Making ActiveRecord faster ... |
1619 |
add_conditions!(sql, options[:conditions], scope) |
|
97403ad5
»
|
miloops |
2008-11-21 |
Add :having option to find,... |
1620 |
add_group!(sql, options[:group], options[:having], scope) |
|
0e452bb0
»
|
dhh |
2007-08-21 |
Fixed that eager loading qu... |
1621 |
|
|
8c91b767
»
|
tarmo |
2008-07-14 |
Fixed postgresql limited ea... |
1622 |
if order && is_distinct |
| |
1623 |
connection.add_order_by_for_association_limiting!(sql, :order => order) |
|
c8b6b482
»
|
Marcel Molina |
2007-10-23 |
Limited eager loading no lo... |
1624 |
else |
| |
1625 |
add_order!(sql, options[:order], scope) |
|
ef4ac31d
»
|
jeremy |
2007-01-11 |
PostgreSQL: use a subselect... |
1626 |
end |
|
0e452bb0
»
|
dhh |
2007-08-21 |
Fixed that eager loading qu... |
1627 |
|
|
c9c18520
»
|
dhh |
2006-03-27 |
Making ActiveRecord faster ... |
1628 |
add_limit!(sql, options, scope) |
|
0e452bb0
»
|
dhh |
2007-08-21 |
Fixed that eager loading qu... |
1629 |
|
|
851dd080
»
|
dhh |
2005-10-18 |
Added support for using lim... |
1630 |
return sanitize_sql(sql) |
| |
1631 |
end |
|
c98b471c
»
|
technoweenie |
2006-10-08 |
Reverted old select_limited... |
1632 |
|
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1633 |
def tables_in_string(string) |
| |
1634 |
return [] if string.blank? |
| |
1635 |
string.scan(/([\.a-zA-Z_]+).?\./).flatten |
| |
1636 |
end |
| |
1637 |
|
|
4ca170fc
»
|
NZKoz |
2008-03-02 |
Improve performance on :inc... |
1638 |
def conditions_tables(options) |
|
2a2afca0
»
|
technoweenie |
2006-04-19 |
Ensure that Associations#in... |
1639 |
# look in both sets of conditions |
| |
1640 |
conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond| |
| |
1641 |
case cond |
| |
1642 |
when nil then all |
| |
1643 |
when Array then all << cond.first |
|
9a4d5577
»
|
Paul |
2008-11-26 |
Ensure hash conditions on r... |
1644 |
when Hash then all << cond.keys |
|
2a2afca0
»
|
technoweenie |
2006-04-19 |
Ensure that Associations#in... |
1645 |
else all << cond |
| |
1646 |
end |
| |
1647 |
end |
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1648 |
tables_in_string(conditions.join(' ')) |
|
4ca170fc
»
|
NZKoz |
2008-03-02 |
Improve performance on :inc... |
1649 |
end |
| |
1650 |
|
| |
1651 |
def order_tables(options) |
|
e94e53f9
»
|
brandon |
2008-06-09 |
fix eager loading with dyna... |
1652 |
order = [options[:order], scope(:find, :order) ].join(", ") |
|
4ca170fc
»
|
NZKoz |
2008-03-02 |
Improve performance on :inc... |
1653 |
return [] unless order && order.is_a?(String) |
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1654 |
tables_in_string(order) |
|
4ca170fc
»
|
NZKoz |
2008-03-02 |
Improve performance on :inc... |
1655 |
end |
| |
1656 |
|
|
b28b54ca
»
|
jdevine |
2008-05-04 |
Make sure needed table join... |
1657 |
def selects_tables(options) |
| |
1658 |
select = options[:select] |
| |
1659 |
return [] unless select && select.is_a?(String) |
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1660 |
tables_in_string(select) |
| |
1661 |
end |
| |
1662 |
|
| |
1663 |
def joined_tables(options) |
| |
1664 |
scope = scope(:find) |
| |
1665 |
joins = options[:joins] |
| |
1666 |
merged_joins = scope && scope[:joins] && joins ? merge_joins(scope[:joins], joins) : (joins || scope && scope[:joins]) |
| |
1667 |
[table_name] + case merged_joins |
| |
1668 |
when Symbol, Hash, Array |
| |
1669 |
if array_of_strings?(merged_joins) |
| |
1670 |
tables_in_string(merged_joins.join(' ')) |
| |
1671 |
else |
| |
1672 |
join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil) |
|
9c7fe7c6
»
|
fcheung |
2008-12-18 |
Don't include table_name twice |
1673 |
join_dependency.join_associations.collect {|join_association| [join_association.aliased_join_table_name, join_association.aliased_table_name]}.flatten.compact |
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1674 |
end |
| |
1675 |
else |
| |
1676 |
tables_in_string(merged_joins) |
| |
1677 |
end |
|
b28b54ca
»
|
jdevine |
2008-05-04 |
Make sure needed table join... |
1678 |
end |
| |
1679 |
|
|
4ca170fc
»
|
NZKoz |
2008-03-02 |
Improve performance on :inc... |
1680 |
# Checks if the conditions reference a table other than the current model table |
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1681 |
def include_eager_conditions?(options, tables = nil, joined_tables = nil) |
| |
1682 |
((tables || conditions_tables(options)) - (joined_tables || joined_tables(options))).any? |
|
851dd080
»
|
dhh |
2005-10-18 |
Added support for using lim... |
1683 |
end |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1684 |
|
|
2a2afca0
»
|
technoweenie |
2006-04-19 |
Ensure that Associations#in... |
1685 |
# Checks if the query order references a table other than the current model's table. |
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1686 |
def include_eager_order?(options, tables = nil, joined_tables = nil) |
| |
1687 |
((tables || order_tables(options)) - (joined_tables || joined_tables(options))).any? |
|
d49a5fcb
»
|
NZKoz |
2006-02-09 |
* Fix pagination problems w... |
1688 |
end |
|
851dd080
»
|
dhh |
2005-10-18 |
Added support for using lim... |
1689 |
|
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1690 |
def include_eager_select?(options, joined_tables = nil) |
| |
1691 |
(selects_tables(options) - (joined_tables || joined_tables(options))).any? |
|
b28b54ca
»
|
jdevine |
2008-05-04 |
Make sure needed table join... |
1692 |
end |
| |
1693 |
|
|
355a8ff2
»
|
jeremy |
2008-01-18 |
Introduce preload query str... |
1694 |
def references_eager_loaded_tables?(options) |
|
c9ab7098
»
|
fcheung |
2008-12-18 |
Ensure :include checks join... |
1695 |
joined_tables = joined_tables(options) |
| |
1696 |
include_eager_order?(options, nil, joined_tables) || include_eager_conditions?(options, nil, joined_tables) || include_eager_select?(options, joined_tables) |
|
355a8ff2
»
|
jeremy |
2008-01-18 |
Introduce preload query str... |
1697 |
end |
| |
1698 |
|
|
5b9b904f
»
|
dhh |
2005-07-10 |
Added support for limit and... |
1699 |
def using_limitable_reflections?(reflections) |
| |
1700 |
reflections.reject { |r| [ :belongs_to, :has_one ].include?(r.macro) }.length.zero? |
| |
1701 |
end |
| |
1702 |
|
|
55854c41
»
|
dhh |
2006-03-04 |
Added cascading eager loadi... |
1703 |
def column_aliases(join_dependency) |
| |
1704 |
join_dependency.joins.collect{|join| join.column_names_with_alias.collect{|column_name, aliased_name| |
|
79823e0b
»
|
NZKoz |
2007-11-10 |
Ensure that column names ar... |
1705 |
"#{connection.quote_table_name join.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}"}}.flatten.join(", ") |
|
057cf491
»
|
dhh |
2005-04-10 |
Added support for has_and_b... |
1706 |
end |
| |
1707 |
|
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
1708 |
def add_association_callbacks(association_name, options) |
|
e19bd169
»
|
jeremy |
2005-10-01 |
Association validation does... |
1709 |
callbacks = %w(before_add after_add before_remove after_remove) |
| |
1710 |
callbacks.each do |callback_name| |
|
7cc446ac
»
|
Marcel Molina |
2006-04-15 |
DRY up association collecti... |
1711 |
full_callback_name = "#{callback_name}_for_#{association_name}" |
|
e19bd169
»
|
jeremy |
2005-10-01 |
Association validation does... |
1712 |
defined_callbacks = options[callback_name.to_sym] |
| |
1713 |
if options.has_key?(callback_name.to_sym) |
| |
1714 |
class_inheritable_reader full_callback_name.to_sym |
|
88f951a5
»
|
jeremy |
2007-10-27 |
Allow association redefinit... |
1715 |
write_inheritable_attribute(full_callback_name.to_sym, [defined_callbacks].flatten) |
| |
1716 |
else |
| |
1717 |
write_inheritable_attribute(full_callback_name.to_sym, []) |
|
e19bd169
»
|
jeremy |
2005-10-01 |
Association validation does... |
1718 |
end |
| |
1719 |
end |
|
4180e57b
»
|
dhh |
2005-07-04 |
Added callback hooks to ass... |
1720 |
end |
|
057cf491
»
|
dhh |
2005-04-10 |
Added support for has_and_b... |
1721 |
|
|
851dd080
»
|
dhh |
2005-10-18 |
Added support for using lim... |
1722 |
def condition_word(sql) |
| |
1723 |
sql =~ /where/i ? " AND " : "WHERE " |
| |
1724 |
end |
|
e19bd169
»
|
jeremy |
2005-10-01 |
Association validation does... |
1725 |
|
|
81d619ea
»
|
jeremy |
2007-09-17 |
Associations macros accept ... |
1726 |
def create_extension_modules(association_id, block_extension, extensions) |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1727 |
if block_extension |
|
de96a866
»
|
adevadeh |
2008-09-12 |
applied patch to fix the as... |
1728 |
extension_module_name = "#{self.to_s.demodulize}#{association_id.to_s.camelize}AssociationExtension" |
|
c8dd66fd
»
|
dhh |
2005-11-06 |
Made association extensions... |
1729 |
|
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1730 |
silence_warnings do |
|
de96a866
»
|
adevadeh |
2008-09-12 |
applied patch to fix the as... |
1731 |
self.parent.const_set(extension_module_name, Module.new(&block_extension)) |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1732 |
end |
|
de96a866
»
|
adevadeh |
2008-09-12 |
applied patch to fix the as... |
1733 |
Array(extensions).push("#{self.parent}::#{extension_module_name}".constantize) |
|
8b5f4e47
»
|
jeremy |
2007-12-22 |
Ruby 1.9 compat: fix warnin... |
1734 |
else |
| |
|