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:
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
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
)
end
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
and then set the primary key to an existing record.
first? I still get a not-null constraint violation on productid on the
SupplierStock.create(
:id => prodid,
:current_stock => s
)
end
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.
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.
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.
Thanks 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:
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!
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: