I will definitely write validations for this - it is easier to provide users with good error messages. I would also like to support this with a database constraint. It seems that control constraints can actually do the job.
Rails has no support for this, which I could find, so you need to create a table with raw sql. You will also need to change the schema builder to :sql , because the rails will not be able to create schema.rb that actually describes this.
I wrote this migration
class CreateFoos < ActiveRecord::Migration def change execute <<SQL CREATE TABLE foos ( id INTEGER PRIMARY KEY, x_id INTEGER, y_id INTEGER, constraint xorit check( (x_id OR y_id) AND NOT(x_id AND y_id)) ) SQL end end
Then in the rails console
Foo.create(:x_id => 1, :y_id => 1)
How can you create a string with neither x_id nor y_id. You can change this by changing the restriction,
(x_id IS NOT NULL OR y_id IS NOT NULL ) AND (x_id IS NULL OR y_id IS NULL)
seemed to work for me
source share