OSDN Git Service

3f8b9d2ceb855f862c27cb50110b410bcaab9e10
[redminele/redminele.git] / ruby / lib / ruby / gems / 1.8 / gems / activerecord-2.3.11 / lib / active_record / associations / belongs_to_association.rb
1 module ActiveRecord
2   module Associations
3     class BelongsToAssociation < AssociationProxy #:nodoc:
4       def create(attributes = {})
5         replace(@reflection.create_association(attributes))
6       end
7
8       def build(attributes = {})
9         replace(@reflection.build_association(attributes))
10       end
11
12       def replace(record)
13         counter_cache_name = @reflection.counter_cache_column
14
15         if record.nil?
16           if counter_cache_name && !@owner.new_record?
17             @reflection.klass.decrement_counter(counter_cache_name, previous_record_id) if @owner[@reflection.primary_key_name]
18           end
19
20           @target = @owner[@reflection.primary_key_name] = nil
21         else
22           raise_on_type_mismatch(record)
23
24           if counter_cache_name && !@owner.new_record?
25             @reflection.klass.increment_counter(counter_cache_name, record.id)
26             @reflection.klass.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name]
27           end
28
29           @target = (AssociationProxy === record ? record.target : record)
30           @owner[@reflection.primary_key_name] = record_id(record) unless record.new_record?
31           @updated = true
32         end
33
34         set_inverse_instance(record, @owner)
35
36         loaded
37         record
38       end
39       
40       def updated?
41         @updated
42       end
43       
44       private
45         def find_target
46           find_method = if @reflection.options[:primary_key]
47                           "find_by_#{@reflection.options[:primary_key]}"
48                         else
49                           "find"
50                         end
51           the_target = @reflection.klass.send(find_method,
52             @owner[@reflection.primary_key_name],
53             :select     => @reflection.options[:select],
54             :conditions => conditions,
55             :include    => @reflection.options[:include],
56             :readonly   => @reflection.options[:readonly]
57           ) if @owner[@reflection.primary_key_name]
58           set_inverse_instance(the_target, @owner)
59           the_target
60         end
61
62         def foreign_key_present
63           !@owner[@reflection.primary_key_name].nil?
64         end
65
66         def record_id(record)
67           record.send(@reflection.options[:primary_key] || :id)
68         end
69
70         def previous_record_id
71           @previous_record_id ||= if @reflection.options[:primary_key]
72                                     previous_record = @owner.send(@reflection.name)
73                                     previous_record.nil? ? nil : previous_record.id
74                                   else
75                                     @owner[@reflection.primary_key_name]
76                                   end
77         end
78
79         # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
80         # has_one associations.
81         def we_can_set_the_inverse_on_this?(record)
82           @reflection.has_inverse? && @reflection.inverse_of.macro == :has_one
83         end
84     end
85   end
86 end