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, PratikIs 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 patchhttp://github.com/rails/rails/commit/e0750d6a5c7f621e4ca12205137c0b13 ...was committed to rails trunk. This patch allows for associations to beflagged 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 endpost = 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 completesthe 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-14The patch can be found athttp://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/61 ...I was asked to submit this patch to the mailing list and solicit anycomments. Does anyone see any obvious holes or ways this functionalityshould change?Thanks, David Dollar
smime.p7s
Description: S/MIME cryptographic signature