Good point David, this can be very dangerous if always enabled due to form injection. But when intentionally enabled, this has the potential to greatly simplify multi-model forms - which I love!
Out of curiosity, have you tried making a multi-model form with this? I can if you want. There are a lot of complexities involved, specifically with regards to when the associated models are saved and what happens when validation fails. Ryan On Jul 17, 4:41 pm, David Dollar <[EMAIL PROTECTED]> wrote: > > On Jul 16, 7:57 pm, Pratik <[EMAIL PROTECTED]> wrote: > >> Has anyone any strong opinions against this ? I'm very interested in > >> hearing more thoughts on this and/or if you have any suggestions to > >> improvise David's approaches. > > >> Thanks, > >> Pratik > > > Is the :accessible specifier necessary? In other words, are we afraid > > something might break if ActiveRecord::Base#new and #create natively > > understood nested hashes as well as the flat hashes that it can accept > > today? > > > Jeff > > The main concern that I have seen presented is that form injection > could cause data to be created/updated around your database > that you did not intend should the attacker carefully craft a form for > submission. > > David > > >> On Jul 14, 6:38 pm, David Dollar <[EMAIL PROTECTED]> wrote: > > >>> Recently the following patch > > >>>http://github.com/rails/rails/commit/e0750d6a5c7f621e4ca12205137c0b13 > >>> ... > > >>> was committed to rails trunk. This patch allows for associations > >>> to be > >>> flagged as :accessible => true and then hydrated from nested hashes > >>> (i.e. nested forms) > > >>> class Post < ActiveRecord::Base > >>> belongs_to :author, :accessible => true > >>> has_many :comments, :accessible => true > >>> end > > >>> post = Post.create({ > >>> :title => 'Accessible Attributes', > >>> :author => { :name => 'David Dollar' }, > >>> :comments => [ > >>> { :body => 'First Post!' }, > >>> { :body => 'Nested Hashes are great!' } > >>> ] > > >>> }) > > >>> post.comments << { :body => 'Another Comment' } > > >>> I have done some work on another patch to allow this same > >>> mechanism to > >>> be used for updating existing rows using nested hashes. This > >>> completes > >>> the work as far as dynamically generating forms and being able to > >>> simply and intuitively push them back into the database. > > >>>http://github.com/ddollar/rails/commit/14a16844bbb3ba9edb14269ce2d0b6 > >>> ... > > >>> This allows for the following: > > >>> # create from a basic hash> p = Post.create(:title => 'Test > >>> Post', :author => { :name => 'David' }) > > >>> => #<Post id: 8, author_id: 8, title: "Test Post", created_at: > >>> "2008-07-14 15:22:53", updated_at: "2008-07-14 15:22:53"> > > >>> # update a singular reference> p.author = { :name => 'Joe' } > > >>> => {:name=>"Joe"} > > >>> # it 'updates' the row in sql, notice the id is still the same> > >>> p.author > > >>> => #<Author id: 8, name: "Joe", created_at: "2008-07-14 15:22:53", > >>> updated_at: "2008-07-14 15:23:03"> > > >>> # create an author with posts from a hash> a = > >>> Author.create(:name => 'David', :posts => [ { :title => 'Post > >>> 1' }, { :title => 'Post 2' } ]) > > >>> => #<Author id: 14, name: "David", created_at: "2008-07-14 > >>> 15:38:18", > >>> updated_at: "2008-07-14 15:38:18"> > > >>> # show the posts> a.posts > > >>> => [#<Post id: 17, author_id: 14, title: "Post 1", created_at: > >>> "2008-07-14 15:38:18", updated_at: "2008-07-14 15:38:18">, #<Post > >>> id: > >>> 18, author_id: 14, title: "Post 2", created_at: "2008-07-14 > >>> 15:38:18", > >>> updated_at: "2008-07-14 15:38:18">] > > >>> # use << to update existing entries (as well as add new ones, > >>> demonstrated later)> a.posts << { :id => 17, :title => 'Post 1 > >>> Updated' } > > >>> => [#<Post id: 17, author_id: 14, title: "Post 1 Updated", > >>> created_at: > >>> "2008-07-14 15:38:18", updated_at: "2008-07-14 15:38:53">, #<Post > >>> id: > >>> 18, author_id: 14, title: "Post 2", created_at: "2008-07-14 > >>> 15:38:18", > >>> updated_at: "2008-07-14 15:38:18">] > > >>> # show posts to verify the update> a.posts > > >>> => [#<Post id: 17, author_id: 14, title: "Post 1 Updated", > >>> created_at: > >>> "2008-07-14 15:38:18", updated_at: "2008-07-14 15:38:53">, #<Post > >>> id: > >>> 18, author_id: 14, title: "Post 2", created_at: "2008-07-14 > >>> 15:38:18", > >>> updated_at: "2008-07-14 15:38:18">] > > >>> # can't update posts that don't belong to the author> a.posts << > >>> { :id => 1, :title => 'Not Allowed' } > > >>> ActiveRecord::RecordNotFound: Couldn't find Post with ID=1 AND > >>> ("posts".author_id = 14) > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/base.rb:1393:in `find_one' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/base.rb:1376:in `find_from_ids' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/base.rb:537:in `find' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/associations/ > >>> association_collection.rb: > >>> 47:in `find' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/associations/ > >>> association_collection.rb: > >>> 103:in `<<' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/associations/ > >>> association_collection.rb: > >>> 99:in `each' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/associations/ > >>> association_collection.rb: > >>> 99:in `<<' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/connection_adapters/abstract/ > >>> database_statements.rb:66:in `transaction' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/transactions.rb:79:in `transaction' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/transactions.rb:98:in `transaction' > >>> from /Users/ddollar/Code/EdgeRailsApp/vendor/rails/ > >>> activerecord/lib/active_record/associations/ > >>> association_collection.rb: > >>> 98:in `<<' > >>> from (irb):12 > > >>> # use = to outright replace all posts> a.posts = [ { :title => > >>> 'Replace Posts' } ] > > >>> => [#<Post id: 19, author_id: 14, title: "Replace Posts", > >>> created_at: > >>> "2008-07-14 15:40:30", updated_at: "2008-07-14 15:40:30">] > > >>> # can even 'replace' using existing posts, the post attributes > >>> will be > >>> updated> a.posts = [ { :id => 19, :title => 'Can Replace This Way > >>> Too' } ] > > >>> => [#<Post id: 19, author_id: 14, title: "Can Replace This Way Too", > >>> created_at: "2008-07-14 15:40:30", updated_at: "2008-07-14 > >>> 15:40:49">] > > >>> # use << also for adding brand new items> a.posts << { :title => > >>> 'New Post' } > > >>> => [#<Post id: 19, author_id: 14, title: "Replace Posts", > >>> created_at: > >>> "2008-07-14 > > >>> The patch can be found at > > >>>http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/61 > >>> ... > > >>> I was asked to submit this patch to the mailing list and solicit any > >>> comments. Does anyone see any obvious holes or ways this > >>> functionality > >>> should change? > > >>> Thanks, > >>> David Dollar > > smime.p7s > 2KDownload --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---