I''m looking at Rails, tryng out an application that is quite similar to the Friends/Phone relational tutorial on rubyonrails.org. I''m puzled by the automatic mangemnt of complex objects (e.g., Foo objects contain an array of Bar objects, with Foo data going in one table, and Bar data going into another, linked by a foreign key). What the tutorial doesn''t seem to show, and I can''t figure out, is how to get Rails to manage the creation/persisting of complex objects without my explcitly adding the code to save the dependant objects . For example, given the Person/Phones example, each person may have zero or more phone numbers. http://rubyonrails.org/show/TutorialBasicRelational When I create a person object, I would want to set all the personal data, and add some phone numbers, ideally in one step: person = Person.new( :name => "Foo bar", :city => "Gotham", :phones => [ ''123-3456'', ''111-3333'' ] ) At some point in my code I would save the person object: person.save and be done, trusting that the person details go into the People table, and phone numbers go into the Phones table. The tutorial shows the creation or editing of a person, with the optional addition of phone numbers, but the code suggests that the code for creating and saving the phone data (as part of a Person object) must be manually added; that Rails does not automagically know that the @phones array should also be stored when the parent person object is saved, and know how to store it. The code here http://rubyonrails.org/show/TutorialRelationalForms manages phones by refering to the person object, but simply uses the person as a sort of phone factory, creating independant objects that are linked via the database, but not asociated as objects per se. In other words, you do not see what I would expect if there was no database involved: @person.phones < Phone.new( value ) or even @person.phones < @person.build_to_phones( value ) Likewise for all the CRUD operations. From playing around, I find that if I delete a Person object, the related phone numbers remain in the Phones table. Have I misunderstood something? Maybe skipped a step someplace? Does Rails know how do do this sort of dependant mapping and persistence? Thanks, James
> Have I misunderstood something? Maybe skipped a step someplace? Does Rails > know how do do this sort of dependant mapping and persistence?You can use @person.phones.create to achieve what you''re looking for "# collection.create(attributes = {}) - returns a new object of the collection type that has been instantiated with attributes and linked to this object through a foreign key and that has already been saved (if it passed the validation)." or build if you don''t want it saved immediately> Thanks, > > James > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers Koz
Michael Koziarski wrote:>>Have I misunderstood something? Maybe skipped a step someplace? Does Rails >>know how do do this sort of dependant mapping and persistence? > > > You can use @person.phones.create to achieve what you''re looking for > > "# collection.create(attributes = {}) - returns a new object of the > collection type that has been instantiated with attributes and linked > to this object through a foreign key and that has already been saved > (if it passed the validation)." > > or build if you don''t want it saved immediatelyOK, this looks promising, and I see now that phone data is automatically saved when the owning person object is saved, though if the person object is new, it apparently must be first explicitly saved before any new associated phone objects can be added (which, assuming the underlying mechanics, makes sense, as they need to get a row ID from the related object). But, continuing with the same tutorial example, it appears that calling ''destroy'' on a person instance deletes the data for that person from the ''people'' table, but leaves the related phone data intact. The code from the tutorial shows this: Person.find(@params["id"]).destroy which successfully removes data from ''people'', but has no effect on any phone records. How can I tell Rails that when a person object with a given id is destroyed, that all related phone data should be destroyed as well? The way it is presented in the tutorial, the ''phones'' table will continue to collect orphaned data. Do I need to code up ''before_destroy'' someplace, and loop over owned collections and explicitly call ''destroy'' on each item? Thanks for the help, James
David Heinemeier Hansson
2004-Nov-22 23:59 UTC
Re: Re: Questions on Managing Complex Objects
> Do I need to code up ''before_destroy'' someplace, and loop over owned > collections and explicitly call ''destroy'' on each item?class Person has_many :phones, :dependent => true end ...by setting dependent to true, AR knows that it should destroy the phones when the person is destroyed. -- David Heinemeier Hansson, http://www.basecamphq.com/ -- Web-based Project Management http://www.rubyonrails.org/ -- Web-application framework for Ruby http://macromates.com/ -- TextMate: Code and markup editor (OS X) http://www.loudthinking.com/ -- Broadcasting Brain
David Heinemeier Hansson wrote:>> Do I need to code up ''before_destroy'' someplace, and loop over owned >> collections and explicitly call ''destroy'' on each item? > > > class Person > has_many :phones, :dependent => true > end > > ...by setting dependent to true, AR knows that it should destroy the > phones when the person is destroyed.Ah, quite sweet. Perhaps this should be in the tutorial? Thanks, James
Abraham Vionas
2004-Nov-23 01:50 UTC
Todo tutorial code not entirely correct? (throwing an exception error)
Below is the wee bit of code in the three files which results in an Exception error of the like: - - - - - - - - - - - - - - NoMethodError in Todo#list Showing /todo/list.rhtml where line #7 raised undefined method `each'' for nil:NilClass 4: </head> 5: 6: <body> 7: <% @items.each do |@item| %> 8: <%= @item.description %> 9: <br /> 10: <% end %> - - - - - -- - - - - - - This error is thrown by the following code in the following files: *IN list.rhtml* <html> <head> <title>My todo list</title> </head> <body> <% @items.each do |@item| %> <%= @item.description %> <br /> <% end %> </body> </html> ************************************** *IN Todo.rb* require ''active_record'' class Todo < ActiveRecord::Base End *************************************** *IN todo_controller.rb* require ''abstract_application'' require ''todo'' class TodoController < AbstractApplicationController helper :todo scaffold :todo end def list @items = Todo.find_all End ************************************** So, anyone have any clue what I''m missing where? I''ve gone back over the tutorial and ensured that I have everything where it''s supposed to be, and I get the expected results up until the creation of list.rhtml and the addition of the code to list.rhtml. Any help and ideas are MUCH appreciated! Regards, Abe
Michael Koziarski
2004-Nov-23 01:52 UTC
Re: Todo tutorial code not entirely correct? (throwing an exception error)
class TodoController < AbstractApplicationController helper :todo scaffold :todo end # This end closes the controller class, delete it and add it down def list @items = Todo.find_all end # HERE. On Mon, 22 Nov 2004 18:50:26 -0700, Abraham Vionas <abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org> wrote:> Below is the wee bit of code in the three files which results in an > Exception error of the like: > > - - - - - - - - - - - - - - > NoMethodError in Todo#list > > Showing /todo/list.rhtml where line #7 raised undefined method `each'' for > nil:NilClass > > 4: </head> > 5: > 6: <body> > 7: <% @items.each do |@item| %> > 8: <%= @item.description %> > 9: <br /> > 10: <% end %> > - - - - - -- - - - - - - > > This error is thrown by the following code in the following files: > > *IN list.rhtml* > <html> > <head> > <title>My todo list</title> > </head> > > <body> > <% @items.each do |@item| %> > <%= @item.description %> > <br /> > <% end %> > </body> > </html> > ************************************** > > *IN Todo.rb* > require ''active_record'' > > class Todo < ActiveRecord::Base > End > *************************************** > > *IN todo_controller.rb* > require ''abstract_application'' > require ''todo'' > > class TodoController < AbstractApplicationController > helper :todo > scaffold :todo > end > > def list > @items = Todo.find_all > End > ************************************** > > So, anyone have any clue what I''m missing where? I''ve gone back over the > tutorial and ensured that I have everything where it''s supposed to be, and I > get the expected results up until the creation of list.rhtml and the > addition of the code to list.rhtml. > > Any help and ideas are MUCH appreciated! > > Regards, Abe > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers Koz
Abraham Vionas
2004-Nov-23 02:11 UTC
RE: Todo tutorial code not entirely correct? (throwing an exception error)
Sounded right to me - but what do I know... No dice. Ugh. Still getting the same error. :( -----Original Message----- From: Michael Koziarski [mailto:koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org] Sent: Monday, November 22, 2004 6:53 PM To: abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org; rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails] Todo tutorial code not entirely correct? (throwing an exception error) class TodoController < AbstractApplicationController helper :todo scaffold :todo end # This end closes the controller class, delete it and add it down def list @items = Todo.find_all end # HERE. On Mon, 22 Nov 2004 18:50:26 -0700, Abraham Vionas <abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org> wrote:> Below is the wee bit of code in the three files which results in an > Exception error of the like: > > - - - - - - - - - - - - - - > NoMethodError in Todo#list > > Showing /todo/list.rhtml where line #7 raised undefined method `each'' > for nil:NilClass > > 4: </head> > 5: > 6: <body> > 7: <% @items.each do |@item| %> > 8: <%= @item.description %> > 9: <br /> > 10: <% end %> > - - - - - -- - - - - - - > > This error is thrown by the following code in the following files: > > *IN list.rhtml* > <html> > <head> > <title>My todo list</title> > </head> > > <body> > <% @items.each do |@item| %> > <%= @item.description %> > <br /> > <% end %> > </body> > </html> > ************************************** > > *IN Todo.rb* > require ''active_record'' > > class Todo < ActiveRecord::Base > End > *************************************** > > *IN todo_controller.rb* > require ''abstract_application'' > require ''todo'' > > class TodoController < AbstractApplicationController > helper :todo > scaffold :todo > end > > def list > @items = Todo.find_all > End > ************************************** > > So, anyone have any clue what I''m missing where? I''ve gone back over > the tutorial and ensured that I have everything where it''s supposed to > be, and I get the expected results up until the creation of list.rhtml > and the addition of the code to list.rhtml. > > Any help and ideas are MUCH appreciated! > > Regards, Abe > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers Koz
Michael Koziarski
2004-Nov-23 02:28 UTC
Re: Todo tutorial code not entirely correct? (throwing an exception error)
> Sounded right to me - but what do I know...Post the exact controller code that you''re using, if it''s just doing a find_all perhaps you can use the scaffolding method?> No dice. Ugh. Still getting the same error. :(Seeing nil:NilClass is essentially a ''Null Pointer'' problem. i.e @items is empty.> -----Original Message----- > From: Michael Koziarski [mailto:koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org] > Sent: Monday, November 22, 2004 6:53 PM > To: abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org; rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > Subject: Re: [Rails] Todo tutorial code not entirely correct? (throwing an > exception error) > > class TodoController < AbstractApplicationController helper :todo scaffold > :todo end # This end closes the controller class, delete it and add it > down > > def list > @items = Todo.find_all > end > > # HERE. > > On Mon, 22 Nov 2004 18:50:26 -0700, Abraham Vionas > <abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org> wrote: > > Below is the wee bit of code in the three files which results in an > > Exception error of the like: > > > > - - - - - - - - - - - - - - > > NoMethodError in Todo#list > > > > Showing /todo/list.rhtml where line #7 raised undefined method `each'' > > for nil:NilClass > > > > 4: </head> > > 5: > > 6: <body> > > 7: <% @items.each do |@item| %> > > 8: <%= @item.description %> > > 9: <br /> > > 10: <% end %> > > - - - - - -- - - - - - - > > > > This error is thrown by the following code in the following files: > > > > *IN list.rhtml* > > <html> > > <head> > > <title>My todo list</title> > > </head> > > > > <body> > > <% @items.each do |@item| %> > > <%= @item.description %> > > <br /> > > <% end %> > > </body> > > </html> > > ************************************** > > > > *IN Todo.rb* > > require ''active_record'' > > > > class Todo < ActiveRecord::Base > > End > > *************************************** > > > > *IN todo_controller.rb* > > require ''abstract_application'' > > require ''todo'' > > > > class TodoController < AbstractApplicationController > > helper :todo > > scaffold :todo > > end > > > > def list > > @items = Todo.find_all > > End > > ************************************** > > > > So, anyone have any clue what I''m missing where? I''ve gone back over > > the tutorial and ensured that I have everything where it''s supposed to > > be, and I get the expected results up until the creation of list.rhtml > > and the addition of the code to list.rhtml. > > > > Any help and ideas are MUCH appreciated! > > > > Regards, Abe > > > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > -- > Cheers > > Koz > > _______________________________________________ > > > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers Koz
Abraham Vionas
2004-Nov-23 02:55 UTC
RE: Todo tutorial code not entirely correct? (throwing an exception error)
Hmmmm... require ''abstract_application'' require ''todo'' def list @items = Todo.find_all end class TodoController < AbstractApplicationController helper :todo scaffold :todo # This end closes the controller class, delete it and add it down End Could the fact that I''m running Rails on Apache cause any of this type of complication? -----Original Message----- From: Michael Koziarski [mailto:koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org] Sent: Monday, November 22, 2004 7:28 PM To: abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org; rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails] Todo tutorial code not entirely correct? (throwing an exception error)> Sounded right to me - but what do I know...Post the exact controller code that you''re using, if it''s just doing a find_all perhaps you can use the scaffolding method?> No dice. Ugh. Still getting the same error. :(Seeing nil:NilClass is essentially a ''Null Pointer'' problem. i.e @items is empty.> -----Original Message----- > From: Michael Koziarski [mailto:koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org] > Sent: Monday, November 22, 2004 6:53 PM > To: abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org; rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > Subject: Re: [Rails] Todo tutorial code not entirely correct? > (throwing an exception error) > > class TodoController < AbstractApplicationController helper :todo > scaffold :todo end # This end closes the controller class, delete it > and add it down > > def list > @items = Todo.find_all > end > > # HERE. > > On Mon, 22 Nov 2004 18:50:26 -0700, Abraham Vionas > <abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org> wrote: > > Below is the wee bit of code in the three files which results in an > > Exception error of the like: > > > > - - - - - - - - - - - - - - > > NoMethodError in Todo#list > > > > Showing /todo/list.rhtml where line #7 raised undefined method `each'' > > for nil:NilClass > > > > 4: </head> > > 5: > > 6: <body> > > 7: <% @items.each do |@item| %> > > 8: <%= @item.description %> > > 9: <br /> > > 10: <% end %> > > - - - - - -- - - - - - - > > > > This error is thrown by the following code in the following files: > > > > *IN list.rhtml* > > <html> > > <head> > > <title>My todo list</title> > > </head> > > > > <body> > > <% @items.each do |@item| %> > > <%= @item.description %> > > <br /> > > <% end %> > > </body> > > </html> > > ************************************** > > > > *IN Todo.rb* > > require ''active_record'' > > > > class Todo < ActiveRecord::Base > > End > > *************************************** > > > > *IN todo_controller.rb* > > require ''abstract_application'' > > require ''todo'' > > > > class TodoController < AbstractApplicationController > > helper :todo > > scaffold :todo > > end > > > > def list > > @items = Todo.find_all > > End > > ************************************** > > > > So, anyone have any clue what I''m missing where? I''ve gone back over > > the tutorial and ensured that I have everything where it''s supposed > > to be, and I get the expected results up until the creation of > > list.rhtml and the addition of the code to list.rhtml. > > > > Any help and ideas are MUCH appreciated! > > > > Regards, Abe > > > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > -- > Cheers > > Koz > > _______________________________________________ > > > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cheers Koz
Vincent Foley
2004-Nov-23 03:59 UTC
Re: Todo tutorial code not entirely correct? (throwing an exception error)
The file should read exactly this: <pre> require ''abstract_application'' require ''todo'' class TodoController < AbstractApplicationController helper :todo scaffold :todo def list @items = Todo.find_all end end </pre> All actions must be /inside/ the controller class. Vincent. On Mon, 22 Nov 2004 19:55:48 -0700, Abraham Vionas <abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org> wrote:> Hmmmm... > > > > require ''abstract_application'' > require ''todo'' > > def list > @items = Todo.find_all > end > > class TodoController < AbstractApplicationController > helper :todo > scaffold :todo > # This end closes the controller class, delete it and add it down > End > > Could the fact that I''m running Rails on Apache cause any of this type of > complication? > > > > > -----Original Message----- > From: Michael Koziarski [mailto:koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org] > Sent: Monday, November 22, 2004 7:28 PM > To: abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org; rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > Subject: Re: [Rails] Todo tutorial code not entirely correct? (throwing an > exception error) > > > Sounded right to me - but what do I know... > > Post the exact controller code that you''re using, if it''s just doing a > find_all perhaps you can use the scaffolding method? > > > No dice. Ugh. Still getting the same error. :( > > Seeing nil:NilClass is essentially a ''Null Pointer'' problem. i.e @items is > empty. > > > -----Original Message----- > > From: Michael Koziarski [mailto:koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org] > > Sent: Monday, November 22, 2004 6:53 PM > > To: abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org; rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > Subject: Re: [Rails] Todo tutorial code not entirely correct? > > (throwing an exception error) > > > > class TodoController < AbstractApplicationController helper :todo > > scaffold :todo end # This end closes the controller class, delete it > > and add it down > > > > def list > > @items = Todo.find_all > > end > > > > # HERE. > > > > On Mon, 22 Nov 2004 18:50:26 -0700, Abraham Vionas > > <abe_ml-jFfP1mdu0rkoaimTfycfilaTQe2KTcn/@public.gmane.org> wrote: > > > Below is the wee bit of code in the three files which results in an > > > Exception error of the like: > > > > > > - - - - - - - - - - - - - - > > > NoMethodError in Todo#list > > > > > > Showing /todo/list.rhtml where line #7 raised undefined method `each'' > > > for nil:NilClass > > > > > > 4: </head> > > > 5: > > > 6: <body> > > > 7: <% @items.each do |@item| %> > > > 8: <%= @item.description %> > > > 9: <br /> > > > 10: <% end %> > > > - - - - - -- - - - - - - > > > > > > This error is thrown by the following code in the following files: > > > > > > *IN list.rhtml* > > > <html> > > > <head> > > > <title>My todo list</title> > > > </head> > > > > > > <body> > > > <% @items.each do |@item| %> > > > <%= @item.description %> > > > <br /> > > > <% end %> > > > </body> > > > </html> > > > ************************************** > > > > > > *IN Todo.rb* > > > require ''active_record'' > > > > > > class Todo < ActiveRecord::Base > > > End > > > *************************************** > > > > > > *IN todo_controller.rb* > > > require ''abstract_application'' > > > require ''todo'' > > > > > > class TodoController < AbstractApplicationController > > > helper :todo > > > scaffold :todo > > > end > > > > > > def list > > > @items = Todo.find_all > > > End > > > ************************************** > > > > > > So, anyone have any clue what I''m missing where? I''ve gone back over > > > the tutorial and ensured that I have everything where it''s supposed > > > to be, and I get the expected results up until the creation of > > > list.rhtml and the addition of the code to list.rhtml. > > > > > > Any help and ideas are MUCH appreciated! > > > > > > Regards, Abe > > > > > > _______________________________________________ > > > Rails mailing list > > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > > > -- > > Cheers > > > > Koz > > > > _______________________________________________ > > > > > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > -- > Cheers > > Koz > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Vincent Foley-Bourgon Blog: http://www.livejournal.com/~gnuvince RSS: http://www.livejournal.com/~gnuvince/data/rss