I have two problems with my Rails code that seem like they should be easy fixes but I can''t figure it out. Anyone looking at the code below will probably think it looks weird or redundant but it''s the only way I''ve gotten it to work. I''d rather do it right though. The first problem is that I have to define the ID outside of the call to new. If I define the ID in new, it never gets defined for whatever reason and I get a not null constraint violation on productid. Why is it that I have to define it outside of new to make it work? The second problem is the call to save. My understanding of save is that it creates a new record if no matching record exists, otherwise it updates the matching record. Well, for some reason I keep getting: Exception encountered: RuntimeError: ERROR C23505 Mduplicate key violates unique constraint supplier_stock_pkey" Fnbtinsert.c L255 R_bt_check_unique: INSERT INTO supplier_stock ("productid", yesterday_stock", "current_stock") VALUES(525542, 0, -1) Why is it not updating instead of trying to create a new record? Thanks. Working code: begin product = SupplierStock.new( :current_stock => s ) product[:productid] = prodid product.save end rescue Exception => e SupplierStock.update( prodid, {:current_stock => s} ) end --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
> I have two problems with my Rails code that seem like they should be > easy fixes but I can''t figure it out. Anyone looking at the code below > will probably think it looks weird or redundant but it''s the only way > I''ve gotten it to work. I''d rather do it right though. The first > problem is that I have to define the ID outside of the call to new. If > I define the ID in new, it never gets defined for whatever reason and > I get a not null constraint violation on productid. Why is it that I > have to define it outside of new to make it work? The second problem > is the call to save. My understanding of save is that it creates a new > record if no matching record exists, otherwise it updates the matching > record. Well, for some reason I keep getting: > > Exception encountered: RuntimeError: ERROR C23505 Mduplicate key > violates unique constraint supplier_stock_pkey" Fnbtinsert.c > L255 R_bt_check_unique: INSERT INTO supplier_stock ("productid", > yesterday_stock", "current_stock") VALUES(525542, 0, -1) > > Why is it not updating instead of trying to create a new record? > Thanks. > > Working code: > > begin > product = SupplierStock.new( > :current_stock => s > ) > product[:productid] = prodid > product.save > end > rescue Exception => e > SupplierStock.update( > prodid, > {:current_stock => s} > ) > endHow come the primary key for your table is "productid" and not just "id" ? Did you change that in your SupplierStock model? Assuming you did... Why arey ou creating a *new* SupplierStock when you have a prodid instead of *finding* the record associated with that prodid? Save will do the right thing, but not if you try and create a *new* record and then set the primary key to an existing record. I think the code you want above should be closer to this: product = SupplierStock.find_by_productid(prodid) product.current_stock = s product.save -philip --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
> How come the primary key for your table is "productid" and not just "id" ? > Did you change that in your SupplierStock model? Assuming you did... > > Why arey ou creating a *new* SupplierStock when you have a prodid instead > of *finding* the record associated with that prodid? > > Save will do the right thing, but not if you try and create a *new* record > and then set the primary key to an existing record. > > I think the code you want above should be closer to this: > > product = SupplierStock.find_by_productid(prodid) > product.current_stock = s > product.save > > -philipGreat, thanks! That fixed the second problem... any ideas on the first? I still get a not-null constraint violation on productid on the create call below. And yes, the primary key is defined as productid in the SupplierStock model. New Code: product = SupplierStock.find_by_productid(prodid) if product product.current_stock = s product.save else SupplierStock.create( :id => prodid, :current_stock => s ) end --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Could you post actual error message and the code that generates it? It also couldn''t hurt to post the relevant snippets from the supplier_stock.rb and the migration. -- 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 25, 11:19 am, Dave Smith <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Could you post actual error message and the code that generates it? It > also couldn''t hurt to post the relevant snippets from the > supplier_stock.rb and the migration. > -- > Posted viahttp://www.ruby-forum.com/.Error occurs on the call to create: CODE: product = SupplierStock.find_by_productid(prodid) if product product.current_stock = s product.save else product = SupplierStock.create( :id => prodid, :current_stock => s ) end ERROR: Exception encountered: RuntimeError: ERROR C23502 Mnull value in column "productid" violates not-null constraint FexecMain.c L1782 ExecConstraints: INSERT INTO supplier_stock ("yesterday_stock", "current_stock") VALUES(0, 0) SupplierStock Class: class SupplierStock < ActiveRecord::Base def self.table_name() "supplier_stock" end def self.primary_key() "productid" end end Table Schema: Table "public.supplier_stock" Column | Type | Modifiers -----------------+---------+-------------------- productid | integer | not null current_stock | integer | not null default 0 yesterday_stock | integer | not null default 0 Indexes: "supplier_stock_pkey" primary key, btree (productid) Foreign-key constraints: "$1" FOREIGN KEY (productid) REFERENCES supplier_products(productid) ON DELETE CASCADE --~--~---------~--~----~------------~-------~--~----~ 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 25, 2007, at 1:14 PM, Matt White wrote:>> How come the primary key for your table is "productid" and not >> just "id" ? >> Did you change that in your SupplierStock model? Assuming you did... >> >> Why arey ou creating a *new* SupplierStock when you have a prodid >> instead >> of *finding* the record associated with that prodid? >> >> Save will do the right thing, but not if you try and create a >> *new* record >> and then set the primary key to an existing record. >> >> I think the code you want above should be closer to this: >> >> product = SupplierStock.find_by_productid(prodid) >> product.current_stock = s >> product.save >> >> -philip > > Great, thanks! That fixed the second problem... any ideas on the > first? I still get a not-null constraint violation on productid on the > create call below. And yes, the primary key is defined as productid in > the SupplierStock model. > > New Code: > > product = SupplierStock.find_by_productid(prodid) > if product > product.current_stock = s > product.save > else > SupplierStock.create( > :id => prodid, > :current_stock => s > ) > endSupplierStock.find_or_create_by_productid(prodid).update_attribute (:current_stock, s) It will hit the database twice (select + update) or three times (select + insert + update) depending on whether the SupplierStock record exists or not, respectively, but if creation is relatively rare with respect to existence, it''s probably not too bad. -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 -~----------~----~----~----~------~----~------~--~---
Same problem with the dynamic find_by statement: CODE: product = SupplierStock.find_or_create_by_productid(prodid) ERROR: Exception encountered: RuntimeError: ERROR C23502 Mnull value in column "productid" violates not-null constraint FexecMain.c L1782 ExecConstraints: INSERT INTO supplier_stock ("yesterday_stock", "current_stock") VALUES(0, 0)> SupplierStock.find_or_create_by_productid(prodid).update_attribute > (:current_stock, s) > > It will hit the database twice (select + update) or three times > (select + insert + update) depending on whether the SupplierStock > record exists or not, respectively, but if creation is relatively > rare with respect to existence, it''s probably not too bad. > > -Rob > > Rob Biedenharn http://agileconsultingllc.com > R...-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 -~----------~----~----~----~------~----~------~--~---
On Jul 25, 2007, at 1:39 PM, Matt White wrote:> On Jul 25, 11:19 am, Dave Smith <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > wrote: >> Could you post actual error message and the code that generates >> it? It >> also couldn''t hurt to post the relevant snippets from the >> supplier_stock.rb and the migration. >> -- >> Posted viahttp://www.ruby-forum.com/. > > Error occurs on the call to create: > > CODE: > > product = SupplierStock.find_by_productid(prodid) > if product > product.current_stock = s > product.save > else > product = SupplierStock.create( > :id => prodid, > :current_stock => s > ) > end > > ERROR: > > Exception encountered: RuntimeError: ERROR C23502 Mnull value in > column "productid" violates not-null constraint FexecMain.c > L1782 ExecConstraints: INSERT INTO supplier_stock > ("yesterday_stock", "current_stock") VALUES(0, 0) > > SupplierStock Class:I think you need to let ActiveRecord know where you''re departing from convention.> class SupplierStock < ActiveRecord::Baseset_table_name "supplier_stock" set_primary_key "productid"> def self.table_name() > "supplier_stock" > end > > def self.primary_key() > "productid" > end > > end > > Table Schema: > > Table "public.supplier_stock" > Column | Type | Modifiers > -----------------+---------+-------------------- > productid | integer | not null > current_stock | integer | not null default 0 > yesterday_stock | integer | not null default 0 > Indexes: > "supplier_stock_pkey" primary key, btree (productid) > Foreign-key constraints: > "$1" FOREIGN KEY (productid) REFERENCES > supplier_products(productid) ON DELETE CASCADEYou might also need to do the create step like: unless prodid.nil? if product = SupplierStock.find_by_id(prodid) product.update_attribute(:current_stock, s) else product = SupplierStock.new do |ss| ss.id = prodid ss.current_stock = s end product.save end end I don''t think you can specify the :id on a create, but you can alter the :id before the new record is saved. In your case, however, you seem to have prodid.nil? to start and that can''t be what you expect. -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 -~----------~----~----~----~------~----~------~--~---
On Jul 25, 12:22 pm, Rob Biedenharn <R...-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org> wrote:> On Jul 25, 2007, at 1:39 PM, Matt White wrote: > > > > > On Jul 25, 11:19 am, Dave Smith <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > > wrote: > >> Could you post actual error message and the code that generates > >> it? It > >> also couldn''t hurt to post the relevant snippets from the > >> supplier_stock.rb and the migration. > >> -- > >> Posted viahttp://www.ruby-forum.com/. > > > Error occurs on the call to create: > > > CODE: > > > product = SupplierStock.find_by_productid(prodid) > > if product > > product.current_stock = s > > product.save > > else > > product = SupplierStock.create( > > :id => prodid, > > :current_stock => s > > ) > > end > > > ERROR: > > > Exception encountered: RuntimeError: ERROR C23502 Mnull value in > > column "productid" violates not-null constraint FexecMain.c > > L1782 ExecConstraints: INSERT INTO supplier_stock > > ("yesterday_stock", "current_stock") VALUES(0, 0) > > > SupplierStock Class: > > I think you need to let ActiveRecord know where you''re departing from > convention. > > > class SupplierStock < ActiveRecord::Base > > set_table_name "supplier_stock" > set_primary_key "productid" > > > > > def self.table_name() > > "supplier_stock" > > end > > > def self.primary_key() > > "productid" > > end > > > end > > > Table Schema: > > > Table "public.supplier_stock" > > Column | Type | Modifiers > > -----------------+---------+-------------------- > > productid | integer | not null > > current_stock | integer | not null default 0 > > yesterday_stock | integer | not null default 0 > > Indexes: > > "supplier_stock_pkey" primary key, btree (productid) > > Foreign-key constraints: > > "$1" FOREIGN KEY (productid) REFERENCES > > supplier_products(productid) ON DELETE CASCADE > > You might also need to do the create step like: > > unless prodid.nil? > if product = SupplierStock.find_by_id(prodid) > product.update_attribute(:current_stock, s) > else > product = SupplierStock.new do |ss| > ss.id = prodid > ss.current_stock = s > end > product.save > end > end > > I don''t think you can specify the :id on a create, but you can alter > the :id before the new record is saved. In your case, however, you > seem to have prodid.nil? to start and that can''t be what you expect. > > -Rob > > Rob Biedenharn http://agileconsultingllc.com > R...-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.orgThanks for your help Rob. Here''s what I''m sticking with: if product = SupplierStock.find_by_productid(prodid) product.update_attribute(:current_stock, s) else product = SupplierStock.new { |ss| ss.id = prodid ss.current_stock = s } product.save end Seems to work fine. But I still never learned why you can''t specify the id when you make a new ActiveRecord object. Here''s a snipped from my script/console with what I mean:>> product = SupplierStock.new({:id => 600000, :current_stock => 3})=> #<SupplierStock:0x6881cc8 @new_record=true, @attributes={"yesterday_stock"=>0, "current_stock"=>3}> ### You can see that the ID is not included in @attributes above>> product.id = 600000=> 600000>> product=> #<SupplierStock:0x6881cc8 @new_record=true, @attributes={"productid"=>600000, "yesterday_stock"=>0, "current_stock"=>3}> ### But now that I specified it OUTSIDE the call to new, it is present. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Matt White wrote:> Seems to work fine. But I still never learned why you can''t specify > the id when you make a new ActiveRecord object. Here''s a snipped from > my script/console with what I mean: > >>> product = SupplierStock.new({:id => 600000, :current_stock => 3}) > => #<SupplierStock:0x6881cc8 @new_record=true, > @attributes={"yesterday_stock"=>0, "current_stock"=>3}> > > ### You can see that the ID is not included in @attributes aboveThe id attribute, like other attr_protected attributes, is protected from mass assignment by hash. You must assign it individually. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
> The id attribute, like other attr_protected attributes, is protected > from mass assignment by hash. You must assign it individually.make product_id just a regular indexed field and not the primary key. Then you can change all that nonsense above to: product = SupplierStock.find_or_create_by_product_id(600000, :current_stock => 3) -- Rick Olson http://lighthouseapp.com http://weblog.techno-weenie.net http://mephistoblog.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 -~----------~----~----~----~------~----~------~--~---
Unfortunately, I did not define the schema - just hired into it. They have a whole platform built on this table so changing it isn''t just a trivial thing. But at least I understand what''s going on now. Thanks! On Jul 28, 12:29 am, "Rick Olson" <technowee...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > The id attribute, like other attr_protected attributes, is protected > > from mass assignment by hash. You must assign it individually. > > make product_id just a regular indexed field and not the primary key. > Then you can change all that nonsense above to: > > product = SupplierStock.find_or_create_by_product_id(600000, > :current_stock => 3) > -- > Rick Olsonhttp://lighthouseapp.comhttp://weblog.techno-weenie.nethttp://mephistoblog.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 -~----------~----~----~----~------~----~------~--~---