Exclude a column in save!


#1

Hi all,
I have a column that peeks its value from a sequence (postgres) some
times. Other times, I set it to a certain value.
This column has a default value of “nextval(‘the_sequence’)”… When I
want that this column peeks the value from the sequence, I do this:

obj = Mymodel.new
obj.some_column1 = blah
obj.some_column2 = blah
obj.some_column3 = blah
obj.save!

but when looking at the logs, this creates a sql statement like this:

INSERT INTO Mymodels (some_column1, some_column2, some_column3,
problem_column) VALUES (blah, blah, blah, NULL);

this is a problem, because it’s passing NULL and it’s not calling the
default value… the only solution I see here is to create a trigger for
insertion, that when the value is NULL set it to the next value from the
sequence…
what’s the rails-way to do this?

thanks!
rolando.-


#2

are you sure the column has something besides “DEFAULT NULL” in the
create table syntax ?

THis seems odd. I think the save should not do this, am I wrong here ?


#3

Adam D. wrote:

are you sure the column has something besides “DEFAULT NULL” in the
create table syntax ?

of course… the create table statement it’s like this:

CREATE TABLE movimientos (

num_documento int DEFAULT nextval(‘num_documento_seq’),

);

regards,


#4

I have done a little work to help solve this problem

It may have been solved elsewhere

There may be a better way - interceding before the ‘INSERT’ sql statment
to delete all ‘NULL’ valued fields that have DEFAULTs.

The way I have solved it is to specifically disable a NULL or nil column
attribute by altering the Base.attributes function.

Try this: <<END_OF_CODE

module ActiveRecord
module Defaults #:nodoc:
def self.append_features(base)
super
base.extend(ClassMethods)
end
module ClassMethods
def default_on_null(*options)
class_eval <<-EOV
include ActiveRecord::Defaults::InstanceMethods
def default_on_null
#{options.inspect}
end

			EOV
		end
	end
	module InstanceMethods
		public
		def attributes(options=nil)
			attributes=super(options)
			if d=default_on_null
				d.each do |de|
					unless attributes[de]
						print "warning: no attribute: #{de}\n" if 

!attributes.member?(de.to_s)
dt=attributes.delete(de.to_s)
end
end
end
attributes
end
end
end
end

<<END_OF_CODE

Put it in your ActiveRecord lib directory and add to active_record.rb :

At the end of requires:
require ‘active_record/defaults’

At the end of the class_eval
include ActiveRecord::Defaults

Cheers


#5

Also …

add default_on_null to your models where needed:

class SubMenu < ActiveRecord::Base
belongs_to :main_menu
default_on_null :sposition,:field2
end

This will allow these fields ( as attributes ) to actually use their
default values when the attributes are nil

Cheers