views:

113

answers:

4

I created a new model in my rails app. Since it's a one-to-one relation with another table, there's no need for the new model to have an id column. Everything is working fine, but for some reason, all of my Shoulda tests on this model are failing. For example:

should_validate_presence_of :first_name

is throwing this error:

ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'my_new_table.id'
in 'field list': SELECT `my_new_table`.id FROM `my_new_table` WHERE 
(`my_new_table`.`some_other_column` IS NULL)  LIMIT 1

Does Shoulda require an ID column? If so, is there a way around this?

+3  A: 

Did you alias the primary key for Rails purposes?

set_primary_key :my_fk_id
MattMcKnight
Where does this belong? In the model along with the validations and associations?
jerhinesmith
A: 

Did you run rake db:migrate and rake db:test:prepare after you created the new model?

ScottD
+1  A: 

Rails expects your models to have an integer id column as a primary key. You can set it to the foreign key like @MattMcKnight suggests but I'd recommend you create the id column even if you don't strictly need it. In my experience it will save you tons of headaches like this, with basically no downside.

samg
A: 

All tables require an id column that's just the way that ActiveRecord works. As MattMcKnight points out, you can designate another column as the primary key. You can also specify that a table have no id column is creatied by providing :id => false as an option to create_table.

Matt's answer covers renaming the primary key in the model definition. Here's how to do it in a migration.

Note, providing the primary key option without giving the id option as false means that you do not have to add to column's definition to the block. Rails will create it for you. And automatically use it in any join tables.

Example:

class CreateTableWithOUtID < ActiveRecord::Migration

  def self.up
    create_table :my_new_table, :primary_key => :another_table_id do |t|
     t.string :some_other_column 
    end
  end

  def self.down
    drop_table, :my_new_table
  end
end
EmFi