public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Revert "Add :accessible option to Associations for allowing mass assignments 
using hash. [#474 state:resolved]"

This reverts commit e0750d6a5c7f621e4ca12205137c0b135cab444a.

Conflicts:

  activerecord/CHANGELOG
  activerecord/lib/active_record/associations.rb
  activerecord/lib/active_record/associations/association_collection.rb
lifo (author)
Wed Sep 10 10:50:01 -0700 2008
commit  9994f0d90248db7d7eae36f0b597a15e8a427612
tree    bec9c6d368cca2b8bb079173a459d37fd473cb4e
parent  b518b6c0d3e7796e303c2396de97a8d901aeb308
...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
20
21
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24
25
0
@@ -20,24 +20,6 @@
0
 
0
 * Fixed that create database statements would always include "DEFAULT NULL" (Nick Sieger) [#334]
0
 
0
-* Add :accessible option to associations for allowing (opt-in) mass assignment. #474. [David Dollar] Example :
0
-
0
-  class Post < ActiveRecord::Base
0
-    belongs_to :author,   :accessible => true
0
-    has_many   :comments, :accessible => true
0
-  end
0
-
0
-  post = Post.create({
0
-    :title    => 'Accessible Attributes',
0
-    :author   => { :name => 'David Dollar' },
0
-    :comments => [
0
-      { :body => 'First Post!' },
0
-      { :body => 'Nested Hashes are great!' }
0
-    ]
0
-  })
0
-
0
-  post.comments << { :body => 'Another Comment' }
0
-
0
 * Add :tokenizer option to validates_length_of to specify how to split up the attribute string. #507. [David Lowenfels] Example :
0
 
0
   # Ensure essay contains at least 100 words.
...
739
740
741
742
743
744
745
746
747
...
855
856
857
858
859
860
861
862
...
973
974
975
976
977
978
979
980
...
1190
1191
1192
1193
1194
1195
1196
1197
...
1266
1267
1268
1269
1270
1271
1272
1273
...
1519
1520
1521
1522
 
1523
1524
1525
1526
1527
1528
1529
1530
...
1534
1535
1536
1537
 
1538
1539
1540
1541
1542
1543
1544
1545
...
1554
1555
1556
1557
 
1558
1559
1560
1561
1562
1563
1564
1565
...
1577
1578
1579
1580
 
1581
1582
1583
...
739
740
741
 
 
 
742
743
744
...
852
853
854
 
 
855
856
857
...
968
969
970
 
 
971
972
973
...
1183
1184
1185
 
 
1186
1187
1188
...
1257
1258
1259
 
 
1260
1261
1262
...
1508
1509
1510
 
1511
1512
1513
1514
1515
 
1516
1517
1518
...
1522
1523
1524
 
1525
1526
1527
1528
1529
 
1530
1531
1532
...
1541
1542
1543
 
1544
1545
1546
1547
1548
 
1549
1550
1551
...
1563
1564
1565
 
1566
1567
1568
1569
0
@@ -739,9 +739,6 @@ module ActiveRecord
0
       #   If true, all the associated objects are readonly through the association.
0
       # [:validate]
0
       #   If false, don't validate the associated objects when saving the parent object. true by default.
0
-      # [:accessible]
0
-      #   Mass assignment is allowed for this assocation (similar to <tt>ActiveRecord::Base#attr_accessible</tt>).
0
-
0
       # Option examples:
0
       #   has_many :comments, :order => "posted_on"
0
       #   has_many :comments, :include => :author
0
@@ -855,8 +852,6 @@ module ActiveRecord
0
       #   If true, the associated object is readonly through the association.
0
       # [:validate]
0
       #   If false, don't validate the associated object when saving the parent object. +false+ by default.
0
-      # [:accessible]
0
-      #   Mass assignment is allowed for this assocation (similar to <tt>ActiveRecord::Base#attr_accessible</tt>).
0
       #
0
       # Option examples:
0
       #   has_one :credit_card, :dependent => :destroy  # destroys the associated credit card
0
@@ -973,8 +968,6 @@ module ActiveRecord
0
       #   If true, the associated object is readonly through the association.
0
       # [:validate]
0
       #   If false, don't validate the associated objects when saving the parent object. +false+ by default.
0
-      # [:accessible]
0
-      #   Mass assignment is allowed for this assocation (similar to <tt>ActiveRecord::Base#attr_accessible</tt>).
0
       #
0
       # Option examples:
0
       #   belongs_to :firm, :foreign_key => "client_of"
0
@@ -1190,8 +1183,6 @@ module ActiveRecord
0
       #   If true, all the associated objects are readonly through the association.
0
       # [:validate]
0
       #   If false, don't validate the associated objects when saving the parent object. +true+ by default.
0
-      # [:accessible<]
0
-      #   Mass assignment is allowed for this assocation (similar to <tt>ActiveRecord::Base#attr_accessible</tt>).
0
       #
0
       # Option examples:
0
       #   has_and_belongs_to_many :projects
0
@@ -1266,8 +1257,6 @@ module ActiveRecord
0
               association = association_proxy_class.new(self, reflection)
0
             end
0
 
0
-            new_value = reflection.build_association(new_value) if reflection.options[:accessible] && new_value.is_a?(Hash)
0
-
0
             if association_proxy_class == HasOneThroughAssociation
0
               association.create_through_record(new_value)
0
               self.send(reflection.name, new_value)
0
@@ -1519,12 +1508,11 @@ module ActiveRecord
0
           :finder_sql, :counter_sql,
0
           :before_add, :after_add, :before_remove, :after_remove,
0
           :extend, :readonly,
0
-          :validate, :accessible
0
+          :validate
0
         ]
0
 
0
         def create_has_many_reflection(association_id, options, &extension)
0
           options.assert_valid_keys(valid_keys_for_has_many_association)
0
-
0
           options[:extend] = create_extension_modules(association_id, extension, options[:extend])
0
 
0
           create_reflection(:has_many, association_id, options, self)
0
@@ -1534,12 +1522,11 @@ module ActiveRecord
0
         @@valid_keys_for_has_one_association = [
0
           :class_name, :foreign_key, :remote, :select, :conditions, :order,
0
           :include, :dependent, :counter_cache, :extend, :as, :readonly,
0
-          :validate, :primary_key, :accessible
0
+          :validate, :primary_key
0
         ]
0
 
0
         def create_has_one_reflection(association_id, options)
0
           options.assert_valid_keys(valid_keys_for_has_one_association)
0
-
0
           create_reflection(:has_one, association_id, options, self)
0
         end
0
 
0
@@ -1554,12 +1541,11 @@ module ActiveRecord
0
         @@valid_keys_for_belongs_to_association = [
0
           :class_name, :foreign_key, :foreign_type, :remote, :select, :conditions,
0
           :include, :dependent, :counter_cache, :extend, :polymorphic, :readonly,
0
-          :validate, :accessible
0
+          :validate
0
         ]
0
 
0
         def create_belongs_to_reflection(association_id, options)
0
           options.assert_valid_keys(valid_keys_for_belongs_to_association)
0
-
0
           reflection = create_reflection(:belongs_to, association_id, options, self)
0
 
0
           if options[:polymorphic]
0
@@ -1577,7 +1563,7 @@ module ActiveRecord
0
             :finder_sql, :delete_sql, :insert_sql,
0
             :before_add, :after_add, :before_remove, :after_remove,
0
             :extend, :readonly,
0
-            :validate, :accessible
0
+            :validate
0
           )
0
 
0
           options[:extend] = create_extension_modules(association_id, extension, options[:extend])
...
110
111
112
113
114
115
116
117
...
286
287
288
289
290
291
292
293
294
295
...
110
111
112
 
 
113
114
115
...
284
285
286
 
 
 
 
287
288
289
0
@@ -110,8 +110,6 @@ module ActiveRecord
0
 
0
         @owner.transaction do
0
           flatten_deeper(records).each do |record|
0
-            record = @reflection.build_association(record) if @reflection.options[:accessible] && record.is_a?(Hash)
0
-
0
             raise_on_type_mismatch(record)
0
             add_record_to_target_with_callbacks(record) do |r|
0
               result &&= insert_record(record) unless @owner.new_record?
0
@@ -286,10 +284,6 @@ module ActiveRecord
0
       # Replace this collection with +other_array+
0
       # This will perform a diff and delete/add only records that have changed.
0
       def replace(other_array)
0
-        other_array.map! do |val|
0
-          val.is_a?(Hash) ? @reflection.build_association(val) : val
0
-        end if @reflection.options[:accessible]
0
-
0
         other_array.each { |val| raise_on_type_mismatch(val) }
0
 
0
         load_target
...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
...
189
190
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
193
194
0
@@ -189,114 +189,6 @@ class AssociationProxyTest < ActiveRecord::TestCase
0
     end
0
   end
0
 
0
-  def test_belongs_to_mass_assignment
0
-    post_attributes   = { :title => 'Associations', :body => 'Are They Accessible?' }
0
-    author_attributes = { :name  => 'David Dollar' }
0
-
0
-    assert_no_difference 'Author.count' do
0
-      assert_raise(ActiveRecord::AssociationTypeMismatch) do
0
-        Post.create(post_attributes.merge({:author => author_attributes}))
0
-      end
0
-    end
0
-
0
-    assert_difference 'Author.count' do
0
-      post = Post.create(post_attributes.merge({:creatable_author => author_attributes}))
0
-      assert_equal post.creatable_author.name, author_attributes[:name]
0
-    end
0
-  end
0
-
0
-  def test_has_one_mass_assignment
0
-    post_attributes    = { :title => 'Associations', :body => 'Are They Accessible?' }
0
-    comment_attributes = { :body  => 'Setter Takes Hash' }
0
-
0
-    assert_no_difference 'Comment.count' do
0
-      assert_raise(ActiveRecord::AssociationTypeMismatch) do
0
-        Post.create(post_attributes.merge({:uncreatable_comment => comment_attributes}))
0
-      end
0
-    end
0
-
0
-    assert_difference 'Comment.count' do
0
-      post = Post.create(post_attributes.merge({:creatable_comment => comment_attributes}))
0
-      assert_equal post.creatable_comment.body, comment_attributes[:body]
0
-    end
0
-  end
0
-
0
-  def test_has_many_mass_assignment
0
-    post               = posts(:welcome)
0
-    post_attributes    = { :title => 'Associations', :body => 'Are They Accessible?' }
0
-    comment_attributes = { :body  => 'Setter Takes Hash' }
0
-
0
-    assert_no_difference 'Comment.count' do
0
-      assert_raise(ActiveRecord::AssociationTypeMismatch) do
0
-        Post.create(post_attributes.merge({:comments => [comment_attributes]}))
0
-      end
0
-      assert_raise(ActiveRecord::AssociationTypeMismatch) do
0
-        post.comments << comment_attributes
0
-      end
0
-    end
0
-
0
-    assert_difference 'Comment.count' do
0
-      post = Post.create(post_attributes.merge({:creatable_comments => [comment_attributes]}))
0
-      assert_equal post.creatable_comments.last.body, comment_attributes[:body]
0
-    end
0
-
0
-    assert_difference 'Comment.count' do
0
-      post.creatable_comments << comment_attributes
0
-      assert_equal post.comments.last.body, comment_attributes[:body]
0
-    end
0
-
0
-    post.creatable_comments = [comment_attributes, comment_attributes]
0
-    assert_equal post.creatable_comments.count, 2
0
-  end
0
-
0
-  def test_has_and_belongs_to_many_mass_assignment
0
-    post                = posts(:welcome)
0
-    post_attributes     = { :title => 'Associations', :body => 'Are They Accessible?' }
0
-    category_attributes = { :name  => 'Accessible Association', :type => 'Category' }
0
-
0
-    assert_no_difference 'Category.count' do
0
-      assert_raise(ActiveRecord::AssociationTypeMismatch) do
0
-        Post.create(post_attributes.merge({:categories => [category_attributes]}))
0
-      end
0
-      assert_raise(ActiveRecord::AssociationTypeMismatch) do
0
-        post.categories << category_attributes
0
-      end
0
-    end
0
-
0
-    assert_difference 'Category.count' do
0
-      post = Post.create(post_attributes.merge({:creatable_categories => [category_attributes]}))
0
-      assert_equal post.creatable_categories.last.name, category_attributes[:name]
0
-    end
0
-
0
-    assert_difference 'Category.count' do
0
-      post.creatable_categories << category_attributes
0
-      assert_equal post.creatable_categories.last.name, category_attributes[:name]
0
-    end
0
-
0
-    post.creatable_categories = [category_attributes, category_attributes]
0
-    assert_equal post.creatable_categories.count, 2
0
-  end
0
-
0
-  def test_association_proxy_setter_can_take_hash
0
-    special_comment_attributes = { :body => 'Setter Takes Hash' }
0
-
0
-    post = posts(:welcome)
0
-    post.creatable_comment = { :body => 'Setter Takes Hash' }
0
-
0
-    assert_equal post.creatable_comment.body, special_comment_attributes[:body]
0
-  end
0
-
0
-  def test_association_collection_can_take_hash
0
-    post_attributes = { :title => 'Setter Takes', :body => 'Hash' }
0
-    david = authors(:david)
0
-
0
-    post = (david.posts << post_attributes).last
0
-    assert_equal post.title, post_attributes[:title]
0
-
0
-    david.posts = [post_attributes, post_attributes]
0
-    assert_equal david.posts.count, 2
0
-  end
0
-
0
   def setup_dangling_association
0
     josh = Author.create(:name => "Josh")
0
     p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh)
...
1
2
 
3
4
5
...
1
 
2
3
4
5
0
@@ -1,5 +1,5 @@
0
 class Author < ActiveRecord::Base
0
-  has_many :posts, :accessible => true
0
+  has_many :posts
0
   has_many :posts_with_comments, :include => :comments, :class_name => "Post"
0
   has_many :posts_with_comments_sorted_by_comment_id, :include => :comments, :class_name => "Post", :order => 'comments.id'
0
   has_many :posts_sorted_by_id_limited, :class_name => "Post", :order => 'posts.id', :limit => 1
...
33
34
35
36
37
38
39
40
41
42
43
44
...
33
34
35
 
 
 
 
 
 
36
37
38
0
@@ -33,12 +33,6 @@ class Post < ActiveRecord::Base
0
   has_and_belongs_to_many :categories
0
   has_and_belongs_to_many :special_categories, :join_table => "categories_posts", :association_foreign_key => 'category_id'
0
 
0
-  belongs_to              :creatable_author,     :class_name => 'Author',   :accessible => true
0
-  has_one                 :uncreatable_comment,  :class_name => 'Comment',  :accessible => false, :order => 'id desc'
0
-  has_one                 :creatable_comment,    :class_name => 'Comment',  :accessible => true,  :order => 'id desc'
0
-  has_many                :creatable_comments,   :class_name => 'Comment',  :accessible => true,  :dependent => :destroy
0
-  has_and_belongs_to_many :creatable_categories, :class_name => 'Category', :accessible => true
0
-
0
   has_many :taggings, :as => :taggable
0
   has_many :tags, :through => :taggings do
0
     def add_joins_and_select

Comments

habermann24 Thu Sep 11 05:08:43 -0700 2008

Why was this reverted? :(

NZKoz Thu Sep 11 06:54:19 -0700 2008

This was discussed on the core list:

http://groups.google.com/group/rubyonrails-core/browse_thread/thread/3c61e00916c365e5

It’s coming back, just post 2.2, it’s not yet ready for a stable release.