Changeset 4123
- Timestamp:
- 04/01/06 20:03:10 (3 years ago)
- Files:
-
- trunk/activerecord/CHANGELOG (modified) (1 diff)
- trunk/activerecord/lib/active_record/associations.rb (modified) (2 diffs)
- trunk/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb (modified) (2 diffs)
- trunk/activerecord/lib/active_record/base.rb (modified) (1 diff)
- trunk/activerecord/test/associations_test.rb (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activerecord/CHANGELOG
r4107 r4123 1 1 *SVN* 2 3 * DEPRECATED: Using additional attributes on has_and_belongs_to_many associations. Instead upgrade your association to be a real join model [DHH] 4 5 * Fixed that records returned from has_and_belongs_to_many associations with additional attributes should be marked as read only (fixes #4512) [DHH] 2 6 3 7 * Do not implicitly mark recordss of has_many :through as readonly but do mark habtm records as readonly (eventually only on join tables without rich attributes). [Marcel Mollina Jr.] trunk/activerecord/lib/active_record/associations.rb
r4084 r4123 699 699 # will give the default join table name of "developers_projects" because "D" outranks "P". 700 700 # 701 # Any additional fields added to the join table will be placed as attributes when pulling records out through 702 # has_and_belongs_to_many associations. This is helpful when have information about the association itself 703 # that you want available on retrieval. Note that any fields in the join table will override matching field names 704 # in the two joined tables. As a consequence, having an "id" field in the join table usually has the undesirable 705 # result of clobbering the "id" fields in either of the other two tables. 701 # Deprecated: Any additional fields added to the join table will be placed as attributes when pulling records out through 702 # has_and_belongs_to_many associations. Records returned from join tables with additional attributes will be marked as 703 # ReadOnly (because we can't save changes to the additional attrbutes). It's strongly recommended that you upgrade any 704 # associations with attributes to a real join model (see introduction). 706 705 # 707 706 # Adds the following methods for retrieval and query. … … 715 714 # also holds the attributes from <tt>join_attributes</tt> (should be a hash with the column names as keys). This can be used to have additional 716 715 # attributes on the join, which will be injected into the associated objects when they are retrieved through the collection. 717 # (collection.concat_with_attributes is an alias to this method). 716 # (collection.concat_with_attributes is an alias to this method). This method is now deprecated. 718 717 # * <tt>collection.delete(object, ...)</tt> - removes one or more objects from the collection by removing their associations from the join table. 719 718 # This does not destroy the objects. trunk/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
r4107 r4123 41 41 42 42 options[:conditions] = conditions 43 options[:joins] = @join_sql44 options[:readonly] ||= !options[:joins].nil?43 options[:joins] = @join_sql 44 options[:readonly] = finding_with_ambigious_select?(options[:select]) 45 45 46 46 if options[:order] && @reflection.options[:order] … … 158 158 @join_sql = "INNER JOIN #{@reflection.options[:join_table]} ON #{@reflection.klass.table_name}.#{@reflection.klass.primary_key} = #{@reflection.options[:join_table]}.#{@reflection.association_foreign_key}" 159 159 end 160 160 161 # Join tables with additional columns on top of the two foreign keys must be considered ambigious unless a select 162 # clause has been explicitly defined. Otherwise you can get broken records back, if, say, the join column also has 163 # and id column, which will then overwrite the id column of the records coming back. 164 def finding_with_ambigious_select?(select_clause) 165 !select_clause && @owner.connection.columns(@reflection.options[:join_table], "Join Table Columns").size != 2 166 end 161 167 end 162 168 end trunk/activerecord/lib/active_record/base.rb
r4116 r4123 851 851 merge = hash[method][key] && params[key] # merge if both scopes have the same key 852 852 if key == :conditions && merge 853 hash[method][key] = [params[key], hash[method][key]].collect{ |sql| "( %s )" % sanitize_sql(sql)}.join(" AND ")853 hash[method][key] = [params[key], hash[method][key]].collect{ |sql| "( %s )" % sanitize_sql(sql) }.join(" AND ") 854 854 elsif key == :include && merge 855 855 hash[method][key] = merge_includes(hash[method][key], params[key]).uniq trunk/activerecord/test/associations_test.rb
r3921 r4123 8 8 require 'fixtures/customer' 9 9 require 'fixtures/order' 10 require 'fixtures/category' 10 11 require 'fixtures/post' 11 12 require 'fixtures/author' … … 1081 1082 1082 1083 class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase 1083 fixtures :accounts, :companies, : developers, :projects, :developers_projects1084 fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects 1084 1085 1085 1086 def test_has_and_belongs_to_many … … 1470 1471 end_sql 1471 1472 end 1473 1474 def test_updating_attributes_on_non_rich_associations 1475 welcome = categories(:technology).posts.first 1476 welcome.title = "Something else" 1477 assert welcome.save! 1478 end 1479 1480 def test_updating_attributes_on_rich_associations 1481 david = projects(:action_controller).developers.first 1482 david.name = "DHH" 1483 assert_raises(ActiveRecord::ReadOnlyRecord) { david.save! } 1484 end 1485 1486 1487 def test_updating_attributes_on_rich_associations_with_limited_find 1488 david = projects(:action_controller).developers.find(:all, :select => "developers.*").first 1489 david.name = "DHH" 1490 assert david.save! 1491 end 1472 1492 1473 1493 def test_join_table_alias