This project is archived and is in readonly mode.
Allow Hash to be passed into AssociationProxy setters and AssociationCollections
Reported by David Dollar | June 23rd, 2008 @ 07:34 PM
Currently when creating a nested form
form_for @books do |f|
f.text_field :isbn
f.fields_for :author do |af|
af.text_field :name
end
end
Book.new(params[:book]) fails because Book#author is passed a HashWithIndifferentAccess (params[:book][:author]) rather than an actual Author
This patch allows Hash to be used in place of an actual ActiveRecord model, and the model itself will be hydrated from the Hash as needed.
Patch is at http://github.com/ddollar/rails/...
Comments and changes to this ticket
-
David Dollar July 2nd, 2008 @ 09:35 PM
Refactored the patch to add ActiveRecord::Base#attr_creatable to permit this functionality
-
Pascal Ehlert July 4th, 2008 @ 08:29 AM
- Tag changed from activerecord, patch to activerecord, patch, tested
Checked it out, tests are passing. Looks good, would like to see this feature soon.
-
Pratik July 8th, 2008 @ 02:08 PM
- Assigned user set to Pratik
-
Pratik July 14th, 2008 @ 12:42 AM
- no changes were found...
-
David Dollar July 14th, 2008 @ 02:54 AM
- no changes were found...
-
Repository July 14th, 2008 @ 02:55 AM
(from [e0750d6a5c7f621e4ca12205137c0b135cab444a]) Add :accessible option to Associations for allowing mass assignments using hash. [#474 state:resolved]
Allows nested Hashes (i.e. from nested forms) to hydrate the appropriate
ActiveRecord models.
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' }
Signed-off-by: Pratik Naik
-
Pratik July 14th, 2008 @ 03:00 AM
- State changed from new to resolved
-
Pascal Ehlert July 14th, 2008 @ 10:39 AM
Okay, I'm a bit in a hurry now and just want to make a quick note before I forgot. I will go into more detail about this later.
If we now also allow attributes for has_many associations, wouldn't it make sense to do it in the way that AttributeFu does it, in order to make it possible to create/update both, existing and new records?
I actually see few cases were only creation is useful.
-
David Dollar July 14th, 2008 @ 01:47 PM
I'm not sure what you mean. Updating currently works with this change.
class Author < ActiveRecord::Base has_many :posts, :accessible => true end class Post < ActiveRecord::Base belongs_to :author, :accessible => true end > Post.create({:title => 'Foo', :author => { :name => 'David' }}) => #<Post id: 1, author_id: 1, title: "Foo", created_at: "2008-07-14 12:42:39", updated_at: "2008-07-14 12:42:39"> > p = Post.find(1) => #<Post id: 1, author_id: 1, title: "Foo", created_at: "2008-07-14 12:42:39", updated_at: "2008-07-14 12:42:39"> > p.author = { :name => 'Joe' } => {:name=>"Joe"}> p.save => true > p => #<Post id: 1, author_id: 2, title: "Foo", created_at: "2008-07-14 12:42:39", updated_at: "2008-07-14 12:43:11"> > p.author => #<Author id: 2, name: "Joe", created_at: "2008-07-14 12:43:11", updated_at: "2008-07-14 12:43:11"> > a = Author.find(2) => #<Author id: 2, name: "Joe", created_at: "2008-07-14 12:43:11", updated_at: "2008-07-14 12:43:11"> > a.posts => [#<Post id: 1, author_id: 2, title: "Foo", created_at: "2008-07-14 12:42:39", updated_at: "2008-07-14 12:43:11">] > a.posts << { :title => 'Another Post' } => [#<Post id: 1, author_id: 2, title: "Foo", created_at: "2008-07-14 12:42:39", updated_at: "2008-07-14 12:43:11">, #<Post id: 2, author_id: 2, title: "Another Post", created_at: "2008-07-14 12:45:49", updated_at: "2008-07-14 12:45:49">] > a.posts.last => #<Post id: 2, author_id: 2, title: "Another Post", created_at: "2008-07-14 12:45:49", updated_at: "2008-07-14 12:45:49">
-
Pascal Ehlert July 14th, 2008 @ 02:02 PM
Sure, it works for has_one and belongs_to, but not so well for has_many.
It will only create a new record and delete the old one which I don't think is a good behavior.
-
David Dollar July 14th, 2008 @ 02:10 PM
I think I see what you mean. Let me see what I can come up with.
--
David Dollar
On Jul 14, 2008, at 9:02 AM, Lighthouse
wrote:
-
David Dollar July 14th, 2008 @ 05:01 PM
- no changes were found...
-
David Dollar July 14th, 2008 @ 05:01 PM
Adds the ability to update existing entries on :accessible => true associations
# 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 15:40:30", updated_at: "2008-07-14 15:40:30">, #<Post id: 20, author_id: 14, title: "New Post", created_at: "2008-07-14 15:43:18", updated_at: "2008-07-14 15:43:18">]
-
James July 15th, 2008 @ 02:43 AM
This approach seems fairly limited.
We couldn't have a form, for example, that would be able to update, and create new child models at once.
My plugin, attribute_fu (mentioned earlier), does the same thing, but supports all the cases where there are both new and saved objects in the hash of hashes. It is a fully transparent solution for creating multi-model forms, including form helpers.
Is there any chance of extending this syntax to support those situations, or sucking attribute_fu down in to core?
If you're unfamiliar with the plugin, checkout this screencast
-
David Dollar July 15th, 2008 @ 02:50 AM
- no changes were found...
-
David Dollar July 15th, 2008 @ 05:42 AM
The second patch mentioned here adds all of the features you are looking for. To mix both creating and updating simply specify some elements of the hash with :id keys and others without.
-
Repository September 10th, 2008 @ 06:51 PM
(from [9994f0d90248db7d7eae36f0b597a15e8a427612]) 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
-
Brian Mitchell September 10th, 2008 @ 09:16 PM
Any word on what might replace this functionality or is it gone for the time being?
-
Sean Kirby November 4th, 2008 @ 03:55 AM
Continued in #1031 and here: http://groups.google.com/group/r...
-
Andrew Vit November 26th, 2008 @ 09:11 AM
Why is this ticket marked "resolved" if the feature was pulled?
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Attachments
Tags
Referenced by
- 127 Params hash is incorrect for nested arrays Don't be so quick to close the issue. It looks like they'...
- 474 Allow Hash to be passed into AssociationProxy setters and AssociationCollections (from [9994f0d90248db7d7eae36f0b597a15e8a427612]) Revert ...
- 1031 handle parameterized associations http://rails.lighthouseapp.com/p...