update_attribute does an insert?

Hello,

I am trying to update an integer value on a table using Rails, but it
complains that I am violating a not-null constraint because I didn't
specify other attributes. My code is as follows:

    sup = Supplier.new
    sup.update_attribute('num_products', total_products)

The error I get is:

RuntimeError: ERROR C23502 Mnull value in column "name" violates
not-null constraint FexecMain.c 1782 RExecConstraints:
INSERT INTO suppliers("name", "num_products", "drop_ship_fee",
"real_name", "return_policy", shipping_terms", "url", "description")
VALUES(NULL, 161, 400, NULL, NULL, NULL, NULL, NULL)

Why is it doing an insert instead of just an update on the single
attribute I want to change? Thanks!

I am trying to update an integer value on a table using Rails, but it
complains that I am violating a not-null constraint because I didn't
specify other attributes. My code is as follows:

   sup = Supplier.new
   sup.update_attribute('num_products', total_products)

You are creating a *new* Supplier in 'sup'. So there's no associated record in the database for you to update the 'num_products' column.

Try something like:

sup = Supplier.find(123)
sup.update_attribute('num_products', total_products)

-philip

If that's really what you want to do, there are a couple other ways to go about it:

   sup = Supplier.new(:num_products => total_products)

   sup = Supplier.new do |s|
     s.num_products = total_products
   end

or if you want it to be on the disk NOW! you might want something like:

   sup = Supplier.create(:name => "Supplier One", :num_products => total_products)

or check out the find_or_create_by_* methods (or even find_or_initialize_by_*) if you might have a record, but are sure you will have one by the time the call is finished.

   sup = Supplier.find_or_initialize_by_name("Supplier One") do |s|
     s.num_products = total_products
     # .. other changes
   end

   sup.save # writes the database once

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com