So I’ve just recently started teaching myself Ruby On Rails and have had my share of hurdles. Most of them have involved the magical world of ActiveRecord, because that’s where I’ve spent the majority of my time in the rails MVC architecture. Also because the model is the foundation of any solid application. Anyway, to the point. I have encountered this error several times while running my tests when it goes to populate the test database using the fixtures.

ActiveRecord::StatementInvalid: Mysql::Error: Unknown column ‘user’ in ‘field list': INSERT INTO `users_posts` (`user`, `thread`, `body`, `active`) VALUES (‘aaron’, ‘one’, ‘Some Text’, true)

This coming from the fixture users_posts.yml which would read something like:

post1:
  user: aaron
  thread: one
  body: Some Text
  active: true

aaron is an entry in users.yml, and ‘one’ is an entry in threads.yml. This is a simple example, but the idea is that users and threads can have many posts. You’ll notice from the SQL that was printed out, that ActiveRecord was looking for a column called user, when in reality it’s user_id. This is something that ActiveRecord does on its own under the covers, so why didn’t it work?

ActiveRecord relies on the associations laid out in your models, so if you mess up or omit the associations inside your models, ActiveRecord will get stuck and assume that the data contained in your fixture is literal (i.e. columnName: data). So the users_posts model should look something like this:

class UsersPosts   belongs_to :user
  belongs_to :thread
end

and the Users model can look something like this

class User   has_many :users_posts
end

and the Threads model something like this

class Thread   has_many :users_posts
  has_many :contributing_users, :class_name 'User', :through => :users_posts
end

But even after setting up these models in this fashion the fixture still messes up? Why? The problem goes back to fundamentals, model names should be singular. Because I named my model users_posts, ActiveRecord choked when it tried to use it to get data into the database. After replacing that model with one called user_post, everything works as expected.

It all falls back to that wonderful Rails principle of convention over configuration. If you stick to convention everything will work just fine. Deviate from it (even a little bit) and you’ll be chasing ghosts for hours.