Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 373
- Log:
Initial import of Radiant 0.9.1, which is now packaged as a gem. This is an
import of the tagged 0.9.1 source checked out from GitHub, which isn't quite
the same as the gem distribution - but it doesn't seem to be available in an
archived form and the installed gem already has modifications, so this is
the closest I can get.
- Author:
- rool
- Date:
- Mon Mar 21 13:40:05 +0000 2011
- Size:
- 4701 Bytes
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) do |reflection| |
11 | attrs = merge_with_conditions(attrs) |
12 | reflection.create_association(attrs) |
13 | end |
14 | end |
15 | |
16 | def create!(attrs = {}, replace_existing = true) |
17 | new_record(replace_existing) do |reflection| |
18 | attrs = merge_with_conditions(attrs) |
19 | reflection.create_association!(attrs) |
20 | end |
21 | end |
22 | |
23 | def build(attrs = {}, replace_existing = true) |
24 | new_record(replace_existing) do |reflection| |
25 | attrs = merge_with_conditions(attrs) |
26 | reflection.build_association(attrs) |
27 | end |
28 | end |
29 | |
30 | def replace(obj, dont_save = false) |
31 | load_target |
32 | |
33 | unless @target.nil? || @target == obj |
34 | if dependent? && !dont_save |
35 | case @reflection.options[:dependent] |
36 | when :delete |
37 | @target.delete unless @target.new_record? |
38 | @owner.clear_association_cache |
39 | when :destroy |
40 | @target.destroy unless @target.new_record? |
41 | @owner.clear_association_cache |
42 | when :nullify |
43 | @target[@reflection.primary_key_name] = nil |
44 | @target.save unless @owner.new_record? || @target.new_record? |
45 | end |
46 | else |
47 | @target[@reflection.primary_key_name] = nil |
48 | @target.save unless @owner.new_record? || @target.new_record? |
49 | end |
50 | end |
51 | |
52 | if obj.nil? |
53 | @target = nil |
54 | else |
55 | raise_on_type_mismatch(obj) |
56 | set_belongs_to_association_for(obj) |
57 | @target = (AssociationProxy === obj ? obj.target : obj) |
58 | end |
59 | |
60 | set_inverse_instance(obj, @owner) |
61 | @loaded = true |
62 | |
63 | unless @owner.new_record? or obj.nil? or dont_save |
64 | return (obj.save ? self : false) |
65 | else |
66 | return (obj.nil? ? nil : self) |
67 | end |
68 | end |
69 | |
70 | protected |
71 | def owner_quoted_id |
72 | if @reflection.options[:primary_key] |
73 | @owner.class.quote_value(@owner.send(@reflection.options[:primary_key])) |
74 | else |
75 | @owner.quoted_id |
76 | end |
77 | end |
78 | |
79 | private |
80 | def find_target |
81 | the_target = @reflection.klass.find(:first, |
82 | :conditions => @finder_sql, |
83 | :select => @reflection.options[:select], |
84 | :order => @reflection.options[:order], |
85 | :include => @reflection.options[:include], |
86 | :readonly => @reflection.options[:readonly] |
87 | ) |
88 | set_inverse_instance(the_target, @owner) |
89 | the_target |
90 | end |
91 | |
92 | def construct_sql |
93 | case |
94 | when @reflection.options[:as] |
95 | @finder_sql = |
96 | "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " + |
97 | "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}" |
98 | else |
99 | @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}" |
100 | end |
101 | @finder_sql << " AND (#{conditions})" if conditions |
102 | end |
103 | |
104 | def construct_scope |
105 | create_scoping = {} |
106 | set_belongs_to_association_for(create_scoping) |
107 | { :create => create_scoping } |
108 | end |
109 | |
110 | def new_record(replace_existing) |
111 | # Make sure we load the target first, if we plan on replacing the existing |
112 | # instance. Otherwise, if the target has not previously been loaded |
113 | # elsewhere, the instance we create will get orphaned. |
114 | load_target if replace_existing |
115 | record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) do |
116 | yield @reflection |
117 | end |
118 | |
119 | if replace_existing |
120 | replace(record, true) |
121 | else |
122 | record[@reflection.primary_key_name] = @owner.id unless @owner.new_record? |
123 | self.target = record |
124 | set_inverse_instance(record, @owner) |
125 | end |
126 | |
127 | record |
128 | end |
129 | |
130 | def merge_with_conditions(attrs={}) |
131 | attrs ||= {} |
132 | attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash) |
133 | attrs |
134 | end |
135 | |
136 | def we_can_set_the_inverse_on_this?(record) |
137 | inverse = @reflection.inverse_of |
138 | return !inverse.nil? |
139 | end |
140 | end |
141 | end |
142 | end |