Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/tags/rel_2-0-2/activerecord/lib/active_record/associations/has_one_association.rb

Revision 7368, 3.1 kB (checked in by nzkoz, 1 year ago)

Formatting, grammar and spelling fixes for the associations documentation. [seanhussey] Closes #8899

Line 
1 module ActiveRecord
2   module Associations
3     class HasOneAssociation < BelongsToAssociation #:nodoc:
4       def initialize(owner, reflection)
5         super
6         construct_sql
7       end
8
9       def create(attrs = {}, replace_existing = true)
10         new_record(replace_existing) { |klass| klass.create(attrs) }
11       end
12
13       def create!(attrs = {}, replace_existing = true)
14         new_record(replace_existing) { |klass| klass.create!(attrs) }
15       end
16
17       def build(attrs = {}, replace_existing = true)
18         new_record(replace_existing) { |klass| klass.new(attrs) }
19       end
20
21       def replace(obj, dont_save = false)
22         load_target
23
24         unless @target.nil?
25           if dependent? && !dont_save && @target != obj
26             @target.destroy unless @target.new_record?
27             @owner.clear_association_cache
28           else
29             @target[@reflection.primary_key_name] = nil
30             @target.save unless @owner.new_record? || @target.new_record?
31           end
32         end
33
34         if obj.nil?
35           @target = nil
36         else
37           raise_on_type_mismatch(obj)
38           set_belongs_to_association_for(obj)
39           @target = (AssociationProxy === obj ? obj.target : obj)
40         end
41
42         @loaded = true
43
44         unless @owner.new_record? or obj.nil? or dont_save
45           return (obj.save ? self : false)
46         else
47           return (obj.nil? ? nil : self)
48         end
49       end
50            
51       private
52         def find_target
53           @reflection.klass.find(:first,
54             :conditions => @finder_sql,
55             :order      => @reflection.options[:order],
56             :include    => @reflection.options[:include]
57           )
58         end
59
60         def construct_sql
61           case
62             when @reflection.options[:as]
63               @finder_sql =
64                 "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +
65                 "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"         
66             else
67               @finder_sql = "#{@reflection.table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"
68           end
69           @finder_sql << " AND (#{conditions})" if conditions
70         end
71        
72         def construct_scope
73           create_scoping = {}
74           set_belongs_to_association_for(create_scoping)
75           { :create => create_scoping }
76         end
77
78         def new_record(replace_existing)
79           # Make sure we load the target first, if we plan on replacing the existing
80           # instance. Otherwise, if the target has not previously been loaded
81           # elsewhere, the instance we create will get orphaned.
82           load_target if replace_existing
83           record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) { yield @reflection.klass }
84
85           if replace_existing
86             replace(record, true)
87           else
88             record[@reflection.primary_key_name] = @owner.id unless @owner.new_record?
89             self.target = record
90           end
91
92           record
93         end
94     end
95   end
96 end
Note: See TracBrowser for help on using the browser.