I’ve been trying to update my Rails project to the new “foxy fixtures”
approach but have run into the following (vexing) problem.
My models looks like this:
class Account < ActiveRecord::Base
has_one :administrator, :class_name => “User”
end
class User < ActiveRecord::Base
belongs_to :account
end
These associations look like they might be backwards.
When I do this in the fixtures:
accounts.yml…
valid_account:
administrator: valid_user
users.yml…
valid_user:
account: valid_account
I get the following:
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column
‘administrator’ in ‘field list’: INSERT INTO accounts (…
Well, yeah. According to your associations, the accounts table does not
have an administrator_id field, and that’s all that fixtures work with.
Is there a way to tell the fixture that “administrator” should
reference the User model?
Probably not. You’ve just discovered the fundamental brokenness of
fixtures: altough they appear to deal with AR classes and fields, in
fact the abstraction is quite leaky and the fixtures are tied fairly
directly to the DB.
This behavior is a misfeature of Rails. The solution is quite simple:
avoid fixtures completely. Use Machinist or something similar instead.
Is there a way to tell the fixture that “administrator” should
reference the User model?
Fixture entries are intentionally tied to the structure of the DB.
Since that’s the case, the association goes on the side with the
foreign key. In your situation, the users table has an account_id
field, and the accounts table has nothing. So:
users.yml
default:
account: default
…will work fine with no annotation on the account side. On a more
general note, I don’t think your keys are in the right place. I’d have
an administrator_id on accounts with a belongs_to pointing at users.
Fixture entries are intentionally tied to the structure of the DB.
Since that’s the case, the association goes on the side with the
foreign key. In your situation, the users table has an account_id
field, and the accounts table has nothing.
Actually the accounts table has an administrator_id (which maps to id
in users) and the users table has an account_id column (which maps to
id in accounts).
users.yml
default:
account: default
…will work fine with no annotation on the account side.
I’ll try this. Thanks.
On a more general note, I don’t think your keys are in the right place. I’d have
an administrator_id on accounts with a belongs_to pointing at users.
Thanks. I may try this. But it feels/reads a little less natural than
the way I currently have it expressed.
Fixture entries are intentionally tied to the structure of the DB. �
Since that’s the case, the association goes on the side with the �
foreign key. In your situation, the users table has an account_id �
field, and the accounts table has nothing.
Actually the accounts table has an administrator_id (which maps to id
in users) and the users table has an account_id column (which maps to
id in accounts).
You don’t need both. In fact, you shouldn’t have both: it decreases
maintainability without providing any benefit.