Ticket #11084: add_readonly_option_to_all_associations.diff
| File add_readonly_option_to_all_associations.diff, 12.4 kB (added by miloops, 7 months ago) |
|---|
-
test/models/company.rb
old new 40 40 :counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = 1000' 41 41 has_many :clients_using_finder_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE 1=1' 42 42 has_many :plain_clients, :class_name => 'Client' 43 has_many :readonly_clients, :class_name => 'Client', :readonly => true 43 44 44 45 has_one :account, :foreign_key => "firm_id", :dependent => :destroy 46 has_one :readonly_account, :foreign_key => "firm_id", :class_name => "Account", :readonly => true 45 47 end 46 48 47 49 class DependentFirm < Company … … 60 62 belongs_to :firm_with_basic_id, :class_name => "Firm", :foreign_key => "firm_id" 61 63 belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of" 62 64 belongs_to :firm_with_condition, :class_name => "Firm", :foreign_key => "client_of", :conditions => ["1 = ?", 1] 65 belongs_to :readonly_firm, :class_name => "Firm", :foreign_key => "firm_id", :readonly => true 63 66 64 67 # Record destruction so we can test whether firm.clients.clear has 65 68 # is calling client.destroy, deleting from the database, or setting -
test/models/project.rb
old new 1 1 class Project < ActiveRecord::Base 2 2 has_and_belongs_to_many :developers, :uniq => true, :order => 'developers.name desc, developers.id desc' 3 has_and_belongs_to_many :readonly_developers, :class_name => "Developer", :readonly => true 3 4 has_and_belongs_to_many :selected_developers, :class_name => "Developer", :select => "developers.*", :uniq => true 4 5 has_and_belongs_to_many :non_unique_developers, :order => 'developers.name desc, developers.id desc', :class_name => 'Developer' 5 6 has_and_belongs_to_many :limited_developers, :class_name => "Developer", :limit => 1 -
test/cases/reflection_test.rb
old new 159 159 end 160 160 161 161 def test_reflection_of_all_associations 162 assert_equal 1 7, Firm.reflect_on_all_associations.size163 assert_equal 1 5, Firm.reflect_on_all_associations(:has_many).size164 assert_equal 2, Firm.reflect_on_all_associations(:has_one).size162 assert_equal 19, Firm.reflect_on_all_associations.size 163 assert_equal 16, Firm.reflect_on_all_associations(:has_many).size 164 assert_equal 3, Firm.reflect_on_all_associations(:has_one).size 165 165 assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size 166 166 end 167 167 -
test/cases/associations_test.rb
old new 468 468 jp.save! 469 469 end 470 470 end 471 472 def test_cant_save_readonly_association 473 assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_firm).readonly_account.save! } 474 assert companies(:first_firm).readonly_account.readonly? 475 end 471 476 472 477 end 473 478 … … 544 549 assert_equal 2, companies(:first_firm).limited_clients.find_all_by_type('Client', :limit => 9_000).length 545 550 end 546 551 552 def test_dynamic_find_all_should_respect_readonly_access 553 companies(:first_firm).readonly_clients.find(:all).each { |c| assert_raise(ActiveRecord::ReadOnlyRecord) { c.save! } } 554 companies(:first_firm).readonly_clients.find(:all).each { |c| assert c.readonly? } 555 end 556 547 557 def test_triple_equality 548 558 assert !(Array === Firm.find(:first).clients) 549 559 assert Firm.find(:first).clients === Array … … 1581 1591 assert_equal post.author_id, author2.id 1582 1592 end 1583 1593 1594 def test_cant_save_readonly_association 1595 assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_client).readonly_firm.save! } 1596 assert companies(:first_client).readonly_firm.readonly? 1597 end 1598 1584 1599 end 1585 1600 1586 1601 … … 1987 2002 assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length 1988 2003 end 1989 2004 2005 def test_dynamic_find_all_should_respect_readonly_access 2006 projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save! } if d.valid?} 2007 projects(:active_record).readonly_developers.each { |d| d.readonly? } 2008 end 2009 1990 2010 def test_new_with_values_in_collection 1991 2011 jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis') 1992 2012 david = DeveloperForProjectWithAfterCreateHook.find_by_name('David') -
lib/active_record/associations/association_proxy.rb
old new 114 114 :offset => @reflection.options[:offset], 115 115 :joins => @reflection.options[:joins], 116 116 :include => @reflection.options[:include], 117 :select => @reflection.options[:select] 117 :select => @reflection.options[:select], 118 :readonly => @reflection.options[:readonly] 118 119 ) 119 120 end 120 121 -
lib/active_record/associations/belongs_to_association.rb
old new 44 44 @reflection.klass.find( 45 45 @owner[@reflection.primary_key_name], 46 46 :conditions => conditions, 47 :include => @reflection.options[:include] 47 :include => @reflection.options[:include], 48 :readonly => @reflection.options[:readonly] 48 49 ) 49 50 end 50 51 -
lib/active_record/associations/has_one_association.rb
old new 53 53 @reflection.klass.find(:first, 54 54 :conditions => @finder_sql, 55 55 :order => @reflection.options[:order], 56 :include => @reflection.options[:include] 56 :include => @reflection.options[:include], 57 :readonly => @reflection.options[:readonly] 57 58 ) 58 59 end 59 60 -
lib/active_record/associations.rb
old new 669 669 # * <tt>:source_type</tt>: Specifies type of the source association used by <tt>has_many :through</tt> queries where the source 670 670 # association is a polymorphic +belongs_to+. 671 671 # * <tt>:uniq</tt> - if set to +true+, duplicates will be omitted from the collection. Useful in conjunction with <tt>:through</tt>. 672 # * <tt>:readonly</tt> - if set to +true+, all the associated objects are readonly through the association. 672 673 # 673 674 # Option examples: 674 675 # has_many :comments, :order => "posted_on" … … 677 678 # has_many :tracks, :order => "position", :dependent => :destroy 678 679 # has_many :comments, :dependent => :nullify 679 680 # has_many :tags, :as => :taggable 681 # has_many :reports, :readonly => true 680 682 # has_many :subscribers, :through => :subscriptions, :source => :user 681 683 # has_many :subscribers, :class_name => "Person", :finder_sql => 682 684 # 'SELECT DISTINCT people.* ' + … … 735 737 # as the default +foreign_key+. 736 738 # * <tt>:include</tt> - specify second-order associations that should be eager loaded when this object is loaded. 737 739 # * <tt>:as</tt>: Specifies a polymorphic interface (See <tt>#belongs_to</tt>). 738 # 740 # * <tt>:readonly</tt> - if set to +true+, the associated object is readonly through the association. 741 # 739 742 # Option examples: 740 743 # has_one :credit_card, :dependent => :destroy # destroys the associated credit card 741 744 # has_one :credit_card, :dependent => :nullify # updates the associated records foreign key value to NULL rather than destroying it 742 745 # has_one :last_comment, :class_name => "Comment", :order => "posted_on" 743 746 # has_one :project_manager, :class_name => "Person", :conditions => "role = 'project_manager'" 744 747 # has_one :attachment, :as => :attachable 748 # has_one :boss, :readonly => :true 745 749 def has_one(association_id, options = {}) 746 750 reflection = create_has_one_reflection(association_id, options) 747 751 … … 811 815 # * <tt>:polymorphic</tt> - specify this association is a polymorphic association by passing +true+. 812 816 # Note: If you've enabled the counter cache, then you may want to add the counter cache attribute 813 817 # to the attr_readonly list in the associated classes (e.g. class Post; attr_readonly :comments_count; end). 818 # * <tt>:readonly</tt> - if set to +true+, the associated object is readonly through the association. 814 819 # 815 820 # Option examples: 816 821 # belongs_to :firm, :foreign_key => "client_of" … … 818 823 # belongs_to :valid_coupon, :class_name => "Coupon", :foreign_key => "coupon_id", 819 824 # :conditions => 'discounts > #{payments_count}' 820 825 # belongs_to :attachable, :polymorphic => true 826 # belongs_to :project, :readonly => true 821 827 def belongs_to(association_id, options = {}) 822 828 reflection = create_belongs_to_reflection(association_id, options) 823 829 … … 970 976 # * <tt>:offset</tt>: An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows. 971 977 # * <tt>:select</tt>: By default, this is <tt>*</tt> as in <tt>SELECT * FROM</tt>, but can be changed if, for example, you want to do a join 972 978 # but not include the joined columns. 979 # * <tt>:readonly</tt> - if set to +true+, all the associated objects are readonly through the association. 973 980 # 974 981 # Option examples: 975 982 # has_and_belongs_to_many :projects 976 983 # has_and_belongs_to_many :projects, :include => [ :milestones, :manager ] 977 984 # has_and_belongs_to_many :nations, :class_name => "Country" 978 985 # has_and_belongs_to_many :categories, :join_table => "prods_cats" 986 # has_and_belongs_to_many :categories, :readonly => true 979 987 # has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql => 980 988 # 'DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}' 981 989 def has_and_belongs_to_many(association_id, options = {}, &extension) … … 1234 1242 :uniq, 1235 1243 :finder_sql, :counter_sql, 1236 1244 :before_add, :after_add, :before_remove, :after_remove, 1237 :extend 1245 :extend, :readonly 1238 1246 ) 1239 1247 1240 1248 options[:extend] = create_extension_modules(association_id, extension, options[:extend]) … … 1244 1252 1245 1253 def create_has_one_reflection(association_id, options) 1246 1254 options.assert_valid_keys( 1247 :class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as 1255 :class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :readonly 1248 1256 ) 1249 1257 1250 1258 create_reflection(:has_one, association_id, options, self) … … 1253 1261 def create_belongs_to_reflection(association_id, options) 1254 1262 options.assert_valid_keys( 1255 1263 :class_name, :foreign_key, :foreign_type, :remote, :conditions, :order, :include, :dependent, 1256 :counter_cache, :extend, :polymorphic 1264 :counter_cache, :extend, :polymorphic, :readonly 1257 1265 ) 1258 1266 1259 1267 reflection = create_reflection(:belongs_to, association_id, options, self) … … 1272 1280 :uniq, 1273 1281 :finder_sql, :delete_sql, :insert_sql, 1274 1282 :before_add, :after_add, :before_remove, :after_remove, 1275 :extend 1283 :extend, :readonly 1276 1284 ) 1277 1285 1278 1286 options[:extend] = create_extension_modules(association_id, extension, options[:extend])