X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=vendor%2Frails%2Factiverecord%2Flib%2Factive_record%2Fassociations%2Fhas_one_association.rb;fp=vendor%2Frails%2Factiverecord%2Flib%2Factive_record%2Fassociations%2Fhas_one_association.rb;h=960323004d1f79f6b131941ac1718a3d66d68deb;hb=d115f2e23823271635bad69229a42cd8ac68debe;hp=0000000000000000000000000000000000000000;hpb=37cb670bf3ddde90b214e591f100ed4446469484;p=depot.git diff --git a/vendor/rails/activerecord/lib/active_record/associations/has_one_association.rb b/vendor/rails/activerecord/lib/active_record/associations/has_one_association.rb new file mode 100644 index 0000000..9603230 --- /dev/null +++ b/vendor/rails/activerecord/lib/active_record/associations/has_one_association.rb @@ -0,0 +1,115 @@ +module ActiveRecord + module Associations + class HasOneAssociation < BelongsToAssociation #:nodoc: + def initialize(owner, reflection) + super + construct_sql + end + + def create(attrs = {}, replace_existing = true) + new_record(replace_existing) do |reflection| + reflection.create_association(attrs) + end + end + + def create!(attrs = {}, replace_existing = true) + new_record(replace_existing) do |reflection| + reflection.create_association!(attrs) + end + end + + def build(attrs = {}, replace_existing = true) + new_record(replace_existing) do |reflection| + reflection.build_association(attrs) + end + end + + def replace(obj, dont_save = false) + load_target + + unless @target.nil? || @target == obj + if dependent? && !dont_save + @target.destroy unless @target.new_record? + @owner.clear_association_cache + else + @target[@reflection.primary_key_name] = nil + @target.save unless @owner.new_record? || @target.new_record? + end + end + + if obj.nil? + @target = nil + else + raise_on_type_mismatch(obj) + set_belongs_to_association_for(obj) + @target = (AssociationProxy === obj ? obj.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 + + protected + def owner_quoted_id + if @reflection.options[:primary_key] + @owner.class.quote_value(@owner.send(@reflection.options[:primary_key])) + else + @owner.quoted_id + end + end + + private + def find_target + @reflection.klass.find(:first, + :conditions => @finder_sql, + :select => @reflection.options[:select], + :order => @reflection.options[:order], + :include => @reflection.options[:include], + :readonly => @reflection.options[:readonly] + ) + end + + def construct_sql + case + when @reflection.options[:as] + @finder_sql = + "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " + + "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}" + else + @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}" + end + @finder_sql << " AND (#{conditions})" if conditions + end + + def construct_scope + create_scoping = {} + set_belongs_to_association_for(create_scoping) + { :create => create_scoping } + end + + def new_record(replace_existing) + # Make sure we load the target first, if we plan on replacing the existing + # instance. Otherwise, if the target has not previously been loaded + # elsewhere, the instance we create will get orphaned. + load_target if replace_existing + record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) do + yield @reflection + end + + if replace_existing + replace(record, true) + else + record[@reflection.primary_key_name] = @owner.id unless @owner.new_record? + self.target = record + end + + record + end + end + end +end