aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations/has_one_association.rb
blob: 1550db69b5f40bf582b1d3dd5fa417b3dae8676b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
module ActiveRecord
  module Associations
    class HasOneAssociation < BelongsToAssociation #:nodoc:
      def initialize(owner, association_name, association_class_name, association_class_primary_key_name, options)
        super

        construct_sql
      end

      def create(attributes = {}, replace_existing = true)
        record = build(attributes, replace_existing)
        record.save
        record
      end

      def build(attributes = {}, replace_existing = true)
        record = @association_class.new(attributes)

        if replace_existing
          replace(record, true) 
        else
          record[@association_class_primary_key_name] = @owner.id unless @owner.new_record?
          self.target = record
        end

        record
      end

      def replace(obj, dont_save = false)
        load_target
        unless @target.nil?
          if dependent? && !dont_save     
            @target.destroy unless @target.new_record?
            @owner.clear_association_cache
          else
            @target[@association_class_primary_key_name] = nil
            @target.save unless @owner.new_record?
          end
        end

        if obj.nil?
          @target = nil
        else
          raise_on_type_mismatch(obj)
          
          obj[@association_class_primary_key_name] = @owner.id unless @owner.new_record?
          @target = obj
        end

        @loaded = true
        unless @owner.new_record? or obj.nil? or dont_save
          return (obj.save ? self : false)
        else
          return (obj.nil? ? nil : self)
        end
      end
            
      private
        def find_target
          @association_class.find(:first, :conditions => @finder_sql, :order => @options[:order])
        end

        def target_obsolete?
          false
        end

        def construct_sql
          @finder_sql = "#{@association_class.table_name}.#{@association_class_primary_key_name} = #{@owner.quoted_id}#{@options[:conditions] ? " AND " + @options[:conditions] : ""}"
        end
    end
  end
end