From 7219e82fe600ff1268b9a89efc7a289ac0108592 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 20 Oct 2005 14:53:04 +0000 Subject: HABTM finder sets :readonly => false. Closes #2525. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2694 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/CHANGELOG | 2 ++ .../has_and_belongs_to_many_association.rb | 1 + activerecord/lib/active_record/base.rb | 8 +++-- activerecord/test/readonly_test.rb | 38 ++++++++++++++-------- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 0c30d221df..c1926a20c7 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *1.12.1* (October 19th, 2005) +* HABTM finders shouldn't return readonly records. #2525 [patrick@lenz.sh] + * Make all tests runnable on their own. #2521. [Blair Zajac ] * Always parenthesize :conditions options so they may be safely combined with STI and constraints. diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index 1fab50418a..1b7adc3f39 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -45,6 +45,7 @@ module ActiveRecord end options[:conditions] = conditions options[:joins] = @join_sql + options[:readonly] ||= false if options[:order] && @options[:order] options[:order] = "#{options[:order]}, #{@options[:order]}" diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 5d594c61a6..aee5c4ede8 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -357,7 +357,7 @@ module ActiveRecord #:nodoc: # * :offset: An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows. # * :joins: An SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id". (Rarely needed). # The records will be returned read-only since they will have attributes that do not correspond to the table's columns. - # Use find_by_sql to circumvent this limitation. + # Pass :readonly => false to override. # * :include: Names associations that should be loaded alongside using LEFT OUTER JOINs. The symbols named refer # to already defined associations. See eager loading under Associations. # * :select: By default, this is * as in SELECT * FROM, but can be changed if you for example want to do a join, but not @@ -384,8 +384,10 @@ module ActiveRecord #:nodoc: def find(*args) options = extract_options_from_args!(args) - # :joins implies :readonly => true - options[:readonly] = true if options[:joins] + # :joins implies :readonly => true if unset. + if options[:joins] and !options.has_key?(:readonly) + options[:readonly] = true + end case args.first when :first diff --git a/activerecord/test/readonly_test.rb b/activerecord/test/readonly_test.rb index cbab35b49a..458cd6886f 100755 --- a/activerecord/test/readonly_test.rb +++ b/activerecord/test/readonly_test.rb @@ -1,31 +1,41 @@ require 'abstract_unit' -require 'fixtures/topic' +require 'fixtures/developer' +require 'fixtures/project' class ReadOnlyTest < Test::Unit::TestCase - fixtures :topics + fixtures :developers, :projects, :developers_projects def test_cant_save_readonly_record - topic = Topic.find(:first) - assert !topic.readonly? + dev = Developer.find(:first) + assert !dev.readonly? - topic.readonly! - assert topic.readonly? + dev.readonly! + assert dev.readonly? assert_nothing_raised do - topic.content = 'Luscious forbidden fruit.' + dev.name = 'Luscious forbidden fruit.' + assert !dev.save + dev.name = 'Forbidden.' end - - assert_raise(ActiveRecord::ReadOnlyRecord) { topic.save } - assert_raise(ActiveRecord::ReadOnlyRecord) { topic.save! } + assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save } + assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save! } end def test_find_with_readonly_option - Topic.find(:all).each { |t| assert !t.readonly? } - Topic.find(:all, :readonly => false).each { |t| assert !t.readonly? } - Topic.find(:all, :readonly => true).each { |t| assert t.readonly? } + Developer.find(:all).each { |d| assert !d.readonly? } + Developer.find(:all, :readonly => false).each { |d| assert !d.readonly? } + Developer.find(:all, :readonly => true).each { |d| assert d.readonly? } end def test_find_with_joins_option_implies_readonly - Topic.find(:all, :joins => '').each { |t| assert t.readonly? } + Developer.find(:all, :joins => '').each { |d| assert d.readonly? } + Developer.find(:all, :joins => '', :readonly => false).each { |d| assert !d.readonly? } + end + + def test_habtm_find_readonly + dev = Developer.find(:first) + dev.projects.each { |p| assert !p.readonly? } + dev.projects.find(:all) { |p| assert !p.readonly? } + dev.projects.find(:all, :readonly => true) { |p| assert p.readonly? } end end -- cgit v1.2.3