<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>activerecord/lib/active_record/associations/through_association_scope.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1242,13 +1242,8 @@ module ActiveRecord
               association = association_proxy_class.new(self, reflection)
             end
 
-            if association_proxy_class == HasOneThroughAssociation
-              association.create_through_record(new_value)
-              self.send(reflection.name, new_value)
-            else
-              association.replace(new_value)
-              association_instance_set(reflection.name, new_value.nil? ? nil : association)
-            end
+            association.replace(new_value)
+            association_instance_set(reflection.name, new_value.nil? ? nil : association)
           end
 
           define_method(&quot;set_#{reflection.name}_target&quot;) do |target|</diff>
      <filename>activerecord/lib/active_record/associations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,10 @@
+require &quot;active_record/associations/through_association_scope&quot;
+
 module ActiveRecord
   module Associations
     class HasManyThroughAssociation &lt; HasManyAssociation #:nodoc:
+      include ThroughAssociationScope
+
       alias_method :new, :build
 
       def create!(attrs = nil)
@@ -72,114 +76,7 @@ module ActiveRecord
 
         def find_target
           return [] unless target_reflection_has_associated_record?
-          @reflection.klass.find(:all,
-            :select     =&gt; construct_select,
-            :conditions =&gt; construct_conditions,
-            :from       =&gt; construct_from,
-            :joins      =&gt; construct_joins,
-            :order      =&gt; @reflection.options[:order],
-            :limit      =&gt; @reflection.options[:limit],
-            :group      =&gt; @reflection.options[:group],
-            :readonly   =&gt; @reflection.options[:readonly],
-            :include    =&gt; @reflection.options[:include] || @reflection.source_reflection.options[:include]
-          )
-        end
-
-        # Construct attributes for associate pointing to owner.
-        def construct_owner_attributes(reflection)
-          if as = reflection.options[:as]
-            { &quot;#{as}_id&quot; =&gt; @owner.id,
-              &quot;#{as}_type&quot; =&gt; @owner.class.base_class.name.to_s }
-          else
-            { reflection.primary_key_name =&gt; @owner.id }
-          end
-        end
-
-        # Construct attributes for :through pointing to owner and associate.
-        def construct_join_attributes(associate)
-          # TODO: revist this to allow it for deletion, supposing dependent option is supported
-          raise ActiveRecord::HasManyThroughCantAssociateThroughHasManyReflection.new(@owner, @reflection) if @reflection.source_reflection.macro == :has_many
-          join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name =&gt; associate.id)
-          if @reflection.options[:source_type]
-            join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] =&gt; associate.class.base_class.name.to_s)
-          end
-          join_attributes
-        end
-
-        # Associate attributes pointing to owner, quoted.
-        def construct_quoted_owner_attributes(reflection)
-          if as = reflection.options[:as]
-            { &quot;#{as}_id&quot; =&gt; owner_quoted_id,
-              &quot;#{as}_type&quot; =&gt; reflection.klass.quote_value(
-                @owner.class.base_class.name.to_s,
-                reflection.klass.columns_hash[&quot;#{as}_type&quot;]) }
-          elsif reflection.macro == :belongs_to
-            { reflection.klass.primary_key =&gt; @owner[reflection.primary_key_name] }
-          else
-            { reflection.primary_key_name =&gt; owner_quoted_id }
-          end
-        end
-
-        # Build SQL conditions from attributes, qualified by table name.
-        def construct_conditions
-          table_name = @reflection.through_reflection.quoted_table_name
-          conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value|
-            &quot;#{table_name}.#{attr} = #{value}&quot;
-          end
-          conditions &lt;&lt; sql_conditions if sql_conditions
-          &quot;(&quot; + conditions.join(') AND (') + &quot;)&quot;
-        end
-
-        def construct_from
-          @reflection.quoted_table_name
-        end
-
-        def construct_select(custom_select = nil)
-          distinct = &quot;DISTINCT &quot; if @reflection.options[:uniq]
-          selected = custom_select || @reflection.options[:select] || &quot;#{distinct}#{@reflection.quoted_table_name}.*&quot;
-        end
-
-        def construct_joins(custom_joins = nil)
-          polymorphic_join = nil
-          if @reflection.source_reflection.macro == :belongs_to
-            reflection_primary_key = @reflection.klass.primary_key
-            source_primary_key     = @reflection.source_reflection.primary_key_name
-            if @reflection.options[:source_type]
-              polymorphic_join = &quot;AND %s.%s = %s&quot; % [
-                @reflection.through_reflection.quoted_table_name, &quot;#{@reflection.source_reflection.options[:foreign_type]}&quot;,
-                @owner.class.quote_value(@reflection.options[:source_type])
-              ]
-            end
-          else
-            reflection_primary_key = @reflection.source_reflection.primary_key_name
-            source_primary_key     = @reflection.through_reflection.klass.primary_key
-            if @reflection.source_reflection.options[:as]
-              polymorphic_join = &quot;AND %s.%s = %s&quot; % [
-                @reflection.quoted_table_name, &quot;#{@reflection.source_reflection.options[:as]}_type&quot;,
-                @owner.class.quote_value(@reflection.through_reflection.klass.name)
-              ]
-            end
-          end
-
-          &quot;INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}&quot; % [
-            @reflection.through_reflection.quoted_table_name,
-            @reflection.quoted_table_name, reflection_primary_key,
-            @reflection.through_reflection.quoted_table_name, source_primary_key,
-            polymorphic_join
-          ]
-        end
-
-        def construct_scope
-          { :create =&gt; construct_owner_attributes(@reflection),
-            :find   =&gt; { :from        =&gt; construct_from,
-                         :conditions  =&gt; construct_conditions,
-                         :joins       =&gt; construct_joins,
-                         :include     =&gt; @reflection.options[:include],
-                         :select      =&gt; construct_select,
-                         :order       =&gt; @reflection.options[:order],
-                         :limit       =&gt; @reflection.options[:limit],
-                         :readonly    =&gt; @reflection.options[:readonly],
-             } }
+          with_scope(construct_scope) { @reflection.klass.find(:all) }
         end
 
         def construct_sql
@@ -204,48 +101,6 @@ module ActiveRecord
           end
         end
 
-        def conditions
-          @conditions = build_conditions unless defined?(@conditions)
-          @conditions
-        end
-
-        def build_conditions
-          association_conditions = @reflection.options[:conditions]
-          through_conditions = build_through_conditions
-          source_conditions = @reflection.source_reflection.options[:conditions]
-          uses_sti = !@reflection.through_reflection.klass.descends_from_active_record?
-
-          if association_conditions || through_conditions || source_conditions || uses_sti
-            all = []
-
-            [association_conditions, source_conditions].each do |conditions|
-              all &lt;&lt; interpolate_sql(sanitize_sql(conditions)) if conditions
-            end
-
-            all &lt;&lt; through_conditions  if through_conditions
-            all &lt;&lt; build_sti_condition if uses_sti
-
-            all.map { |sql| &quot;(#{sql})&quot; } * ' AND '
-          end
-        end
-
-        def build_through_conditions
-          conditions = @reflection.through_reflection.options[:conditions]
-          if conditions.is_a?(Hash)
-            interpolate_sql(sanitize_sql(conditions)).gsub(
-              @reflection.quoted_table_name,
-              @reflection.through_reflection.quoted_table_name)
-          elsif conditions
-            interpolate_sql(sanitize_sql(conditions))
-          end
-        end
-        
-        def build_sti_condition
-          @reflection.through_reflection.klass.send(:type_condition)
-        end
-
-        alias_method :sql_conditions, :conditions
-
         def has_cached_counter?
           @owner.attribute_present?(cached_counter_attribute_name)
         end</diff>
      <filename>activerecord/lib/active_record/associations/has_many_through_association.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,16 @@
+require &quot;active_record/associations/through_association_scope&quot;
+
 module ActiveRecord
   module Associations
-    class HasOneThroughAssociation &lt; HasManyThroughAssociation
+    class HasOneThroughAssociation &lt; HasOneAssociation
+      include ThroughAssociationScope
+
+      def replace(new_value)
+        create_through_record(new_value)
+        @target = new_value
+      end
+
+      private
 
       def create_through_record(new_value) #nodoc:
         klass = @reflection.through_reflection.klass
@@ -15,16 +25,8 @@ module ActiveRecord
       end
 
     private
-      def find(*args)
-        super(args.merge(:limit =&gt; 1))
-      end
-
       def find_target
-        super.first
-      end
-
-      def reset_target!
-        @target = nil
+        with_scope(construct_scope) { @reflection.klass.find(:first) }
       end
     end
   end</diff>
      <filename>activerecord/lib/active_record/associations/has_one_through_association.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8db190acbae5d2a6f25d42d4137793a720a1689c</id>
    </parent>
  </parents>
  <author>
    <name>Adam Milligan</name>
    <email>amilligan@pivotallabs.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/54a5446641e4386285231385700b95a223931bff</url>
  <id>54a5446641e4386285231385700b95a223931bff</id>
  <committed-date>2009-06-12T13:52:51-07:00</committed-date>
  <authored-date>2009-05-10T16:20:16-07:00</authored-date>
  <message>HasOneThroughAssociation still shouldn't derive from HasManyThroughAssociation.

[#1642 state:committed]

Signed-off-by: Jeremy Kemper &lt;jeremy@bitsweat.net&gt;</message>
  <tree>f2c00aac7b43a381ec4bd5f9f5cc26634243fe96</tree>
  <committer>
    <name>Jeremy Kemper</name>
    <email>jeremy@bitsweat.net</email>
  </committer>
</commit>
