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.-
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 ?
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,
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
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