Removing a default value for a foreign key with not null set

Hi all,

For various reasons I need to have foreign keys with not null
constraints.
Eg:

create_table :people do |t|
t.column :name, :string
t.column :household_id, :integer, :null => false
end

create_table :households do |t|
t.column :name, :string
end

add_foreign_key_constraint :people, :household_id, :households, :id

So the people table has a foreign key into households (household_id),
and
not null is enabled on the column.

My problem is that I get default values of 0 for household_id when
instantiating new Person object.

Person.new.household_id # == 0

validates_presence_of :household_id then passes because of the 0 value,
and
the insert fails because 0 is not a valid foreign key.

A simple fix is to use a before_validation and remove and 0 values for
_id
fields, but I’m looking for a cleaner solution:

class Person < ActiveRecord::Base
belongs_to :household
validates_presence_of :household_id

def before_validation
attributes.each do |key, value|
self[key] = nil if value == 0 and key.ends_with?(’_id’)
end
end
end

Is there a better way?

Cheers, Jonathan.

Hi Jonathan

Put a default value of null (or nil in migrations I suppose) in your DB
setup

Then there is no worries about removing it :slight_smile:

Unfortunately it’s not that simple. When you’ve specified NOT NULL in
Mysql
, you can’t give the column a default of null.

ERROR 1067 (42000): Invalid default value for ‘person_id’

That’s fair enough because you’ve said you don’t want nulls allowed, and
then asked for a default of null.

Any other suggestions?

-Jonathan.

Ok Sorry I missed the first part… My bad

I think you can use another validation here.

The validates_associated method checks the validity of the associated
model. Note it should be used after a call to validates_presence_of

The docs can be found at

http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000820

Please see below in the model definition.

On 4/27/06, Jonathan V. [email protected] wrote:

Then there is no worries about removing it :slight_smile:
t.column :name, :string
and not null is enabled on the column.
_id fields, but I’m looking for a cleaner solution:

class Person < ActiveRecord::Base
belongs_to :household
validates_presence_of :household_id

    validates_associated :household_id
   end