Hi, I''m trying to find a way in RoR to retrieve the id of the last record I just saved to a database. I know there is something like LAST_INSERT_ID on MySQL, but I don''t seem to find how to use it - if it is possible in RoR. What is the right way to get that ID in RoR? IS there a way to retrieve it? Help greatly appriciated. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> Hi, I''m trying to find a way in RoR to retrieve the id of the last > record I just saved to a database. > > (...) > > What is the right way to get that ID in RoR? IS there a way to > retrieve it?If you used ActiveRecord to insert, you can just read the ''id'' attribute of the last inserted object. Say you do: elephant = Elephant.create :name => ''Fred'' Then elephant.id is your newly inserted id. -- Jordi --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Jul 5, 2007, at 7:27 AM, Rudy wrote:> Hi, > I''m trying to find a way in RoR to retrieve the id of the last record > I just saved to a database. > > I know there is something like LAST_INSERT_ID on MySQL, but I don''t > seem to find how to use it - if it is possible in RoR. > > What is the right way to get that ID in RoR? IS there a way to > retrieve it? > > Help greatly appriciated.mymodel.save! puts "Last ID is #{mymodel.id}" Is that helpful? If not, perhaps: last_id = MyModel.maximum(''id'') Anything else is likely database specific. -Rob Rob Biedenharn http://agileconsultingllc.com Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Rob Biedenharn wrote:> last_id = MyModel.maximum(''id'') > > Anything else is likely database specific.We do that one in tests to find the last-added record. Wouldn''t the ''id'' roll over if we test >4 billion times? -- Phlip http://www.oreilly.com/catalog/9780596510657/ "Test Driven Ajax (on Rails)" assert_xpath, assert_javascript, & assert_ajax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Jul 5, 2007, at 10:57 AM, Phlip wrote:> Rob Biedenharn wrote: >> last_id = MyModel.maximum(''id'') >> >> Anything else is likely database specific. > > We do that one in tests to find the last-added record. > > Wouldn''t the ''id'' roll over if we test >4 billion times? > > -- > Phlip > http://www.oreilly.com/catalog/9780596510657/ > "Test Driven Ajax (on Rails)" > assert_xpath, assert_javascript, & assert_ajaxSure, but that''s a different problem ;-) -Rob Rob Biedenharn http://agileconsultingllc.com Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Rob Biedenharn wrote:> On Jul 5, 2007, at 7:27 AM, Rudy wrote: >> Help greatly appriciated. > mymodel.save! > puts "Last ID is #{mymodel.id}" > > Is that helpful? If not, perhaps: > > last_id = MyModel.maximum(''id'') > > Anything else is likely database specific. > > -Rob > > Rob Biedenharn http://agileconsultingllc.com > Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.orgJordi had the solution, the id is updated on save/save!, just call the property you want from your model. Using MyModel.maximum(''id'') to find the last inserted id is really not a good idea. The reason is that you can NEVER ensure that there wasn''t another insert into your database in between your model.save! and MyModel.maximum(''id'') calls no matter how short the time frame in between them. So this is not a good practice at all. Hope this helps. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Phlip wrote:> > We do that one in tests to find the last-added record. > > Wouldn''t the ''id'' roll over if we test >4 billion times? > > -- > Phlip > http://www.oreilly.com/catalog/9780596510657/ > "Test Driven Ajax (on Rails)" > assert_xpath, assert_javascript, & assert_ajaxIf you do that many tests I''m sending you a medal. ;) If you that concerned use a bigger unsigned data type (like say unsigned long int in Mysql) or something like a 64 bit GUUID or Serial UUID. OR, easier than all that, drop the database / tables in between tests and use migrations / fixtures to ''build them up'' again when ready. May add a bit of overhead to you timing for execution but it will reset all the internal counters in the DB and you''ll always restart at ''1''. (Or whatever you set minimum is). HTH. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Jul 5, 2007, at 1:56 PM, Jean Nibee wrote:> Rob Biedenharn wrote: >> On Jul 5, 2007, at 7:27 AM, Rudy wrote: >>> Help greatly appriciated. >> mymodel.save! >> puts "Last ID is #{mymodel.id}" >> >> Is that helpful? If not, perhaps: >> >> last_id = MyModel.maximum(''id'') >> >> Anything else is likely database specific. >> >> -Rob >> >> Rob Biedenharn http://agileconsultingllc.com >> Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org > > Jordi had the solution, the id is updated on save/save!, just call the > property you want from your model.Just to set the record straight, that was my first suggestion, too. Just look! Since that only works when you were the one creating that last record, I also noted the other possibility. The OP''s question sounded like the simple mymodel.id would work, but that''s such an obvious thing (for *me*) that I offered something that might not have been obvious.> > Using MyModel.maximum(''id'') to find the last inserted id is really > not a > good idea. The reason is that you can NEVER ensure that there wasn''t > another insert into your database in between your model.save! and > MyModel.maximum(''id'') calls no matter how short the time frame in > between them. > > So this is not a good practice at all. > > Hope this helps.I don''t recall if the OP (Rudy?) has chimed back into the discussion, but it would help if he clarified how/if this has helped. -Rob Rob Biedenharn http://agileconsultingllc.com Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Rob Biedenharn wrote:> Just to set the record straight, that was my first suggestion, too. > Just look! Since that only works when you were the one creating that > last record, I also noted the other possibility.<snipped> Sorry I should have given credit to EVERYONE on the proper solutions, I just took the lazy way out and sent a kudo''s to Jordi. My apologies. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Jul 5, 2007, at 8:57 AM, Phlip wrote:> We do that one in tests to find the last-added record.Maybe I''m paranoid, but doesn''t that run the risk of a different row getting created before you can do that? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi guys, thanks for all the help. Greatly appriciated. It did clarify it. What I use now (and tell me please if this is wrong for any reason) is car=Car.create!(:make => foo) after that, car.id is indeed the id from the newly inserted record. In a way, once you know, it seems so obvious, and it was stated somewhere in the Agile Web Development book as well. (p310) But it was hard to find - as usual for me. :-( I hope that, by having it written out here, as you guys so greatly did, anyone looking for the answer on this question can now find it here as well. This discussiongroup can not be praisedf enough! Rudy On 6 jul, 05:28, George Bailey <listcatc...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Jul 5, 2007, at 8:57 AM, Phlip wrote: > > > We do that one in tests to find the last-added record. > > Maybe I''m paranoid, but doesn''t that run the risk of a different row > getting created before you can do that?--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Rudy wrote:> car=Car.create!(:make => foo) > > after that, car.id is indeed the id from the newly inserted > record.Someone here doesn''t remember the Bad Old Days... - you had to research how to query that freaking ID correctly - you had to research AGAIN to figure out how to find it for each type of database you use - you had to research _AGAIN_ to make sure the number didn''t change when you went to different database connections and/or threads - you had to give up and re-query the record you just wrote back out of the database, just to robustly get its ID When someone scarred by all those experiences tries to use ActiveRecord, and the documentation doesn''t exactly say "the correct id always pops into your database record when the wind blows", you tend to forget how lean and creative all your database activities can be! -- Phlip http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
George Bailey wrote:>> We do that one in tests to find the last-added record. > > Maybe I''m paranoid,Maybe you are test-infected? (-;> but doesn''t that run the risk of a different row > getting created before you can do that?Yes. I just thought of a fix: record = assert_latest Record do get :create_record, :value => ''foo'' end assert_equal ''foo'', record.value If we assume monotonic IDs, we can implement that by fetching Record.maximum(id) before the block, then fetching Record.find_by_id(id + 1) after the block. Now we know we have the first new Record which our tested code created. That''s probably more robust, and test-isolating, than fetching the very last record! I think I''l go write that one and retrofit it into a few places... -- Phlip http://www.oreilly.com/catalog/9780596510657/ "Test Driven Ajax (on Rails)" assert_xpath, assert_javascript, & assert_ajax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jean Nibee wrote:> OR, easier than all that, drop the database / tables in between tests > and use migrations / fixtures to ''build them up'' again when ready. May > add a bit of overhead to you timing for execution but it will reset all > the internal counters in the DB and you''ll always restart at ''1''. (Or > whatever you set minimum is).Occurs to me that many of our projects have a "super-test" Rake task to rebuild the database just like that. So, no 4-billionth test run bug (or award) for us! -- Phlip --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Jul 6, 2007, at 6:40 PM, Phlip wrote:> Yes. I just thought of a fix: > > record = assert_latest Record do > get :create_record, :value => ''foo'' > end > > assert_equal ''foo'', record.valueAnd now if one slips in behind you, you can have a valid record that fails that test ;-) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
George Bailey wrote:>> record = assert_latest Record do >> get :create_record, :value => ''foo'' >> end >> >> assert_equal ''foo'', record.value > > And now if one slips in behind you, you can have a valid record that > fails that test ;-)That''s why we run the tests every few edits. The faster they go, the more we write, and the sloppier they can get. An edit that pushed a record in where we don''t suspect it is a bad edit, even if the user is indeed waiting for that record. When the test fails, we back off and try again. If the test fails again, we might examine why, and we might find a cleverer and more decoupled way to add that record. So frequent test runs make sloppy tests _more_ valuable and cost-effective than arbitrarily correct and complex tests. -- Phlip http://www.oreilly.com/catalog/9780596510657/ "Test Driven Ajax (on Rails)" assert_xpath, assert_javascript, & assert_ajax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
In my case #I CREATE THE ADD @anuncio = Anuncio.new(params[:anuncio]) @anuncio.categoria_id = @cat.id @anuncio.ip = request.remote_ip #THEN I SAVE IT if @anuncio.save # I GENERATE THE SEO LINK USING THE ID OF THE LAST INSERT t = @anuncio.titulo.to_s.downcase.strip.gsub(/[^-_ \s[:alnum:]]/, '''').squeeze('' '').tr('' '', ''_'') (t.blank?) ? ''_'' : t @anuncio.seo = t + ''_'' + @anuncio.id.to_s #THEN SAVE AGAIN @anuncio.save I dont like this too mutch, 2 saves for the same inserted add, but thats the way things go. Bruno Sacco On Jul 7, 5:00 am, "Phlip" <phlip2...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> George Bailey wrote: > >> record = assert_latest Record do > >> get :create_record, :value => ''foo'' > >> end > > >> assert_equal ''foo'', record.value > > > And now if one slips in behind you, you can have a valid record that > > fails that test ;-) > > That''s why we run the tests every few edits. The faster they go, the more we > write, and the sloppier they can get. An edit that pushed a record in where > we don''t suspect it is a bad edit, even if the user is indeed waiting for > that record. > > When the test fails, we back off and try again. If the test fails again, we > might examine why, and we might find a cleverer and more decoupled way to > add that record. > > So frequent test runs make sloppy tests _more_ valuable and cost-effective > than arbitrarily correct and complex tests. > > -- > Phlip > http://www.oreilly.com/catalog/9780596510657/ > "Test Driven Ajax (on Rails)" > assert_xpath, assert_javascript, & assert_ajax--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mindstorm wrote:> In my case > > #I CREATE THE ADD > @anuncio = Anuncio.new(params[:anuncio]) > @anuncio.categoria_id = @cat.idWould this be safer? @anuncio.categoria = @cat> @anuncio.ip = request.remote_ip > > #THEN I SAVE IT > if @anuncio.save > > # I GENERATE THE SEO LINK USING THE ID OF THE LAST INSERT > t = @anuncio.titulo.to_s.downcase.strip.gsub(/[^-_ > \s[:alnum:]]/, '''').squeeze('' '').tr('' '', ''_'') > (t.blank?) ? ''_'' : t > @anuncio.seo = t + ''_'' + @anuncio.id.to_s@anuncio.update_attribute :seo, t + ... Then no save. Do it in one line.> #THEN SAVE AGAIN > @anuncio.save > > I dont like this too mutch, 2 saves for the same inserted add, but > thats the way things go.Can you override the after_create handler? That or a similar handler might be called after the first time a model record is created, and when its id field is ready. -- Phlip http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---