3

I have a User model and an Account model. The user has many accounts and the accounts belong to one user. I have the models and associations all set up. Now I want to make one of those accounts the "primary account". What is the best way to set up the associations? I added a primary_account_id column to my user table and set up the associations like this but it didn't work. Any tips?

class User < ActiveRecord::Base
   has_many :accounts
   has_one :primary_account, :class_name => "Account"
end

class Account < ActiveRecord::Base
   belongs_to :user
end

Edit

I see this question Rails model that has both 'has_one' and 'has_many' but with some contraints which is very similar and the second answer makes the suggestion that I tried. However when I use it rails ignores the column that I've made and just grabs the first one in the table:

>> u = User.find(1)
  User Load (3.9ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
=> #<User id: 1, email: "XXXXXXX@gmail.com", created_at: "2012-03-15 22:34:39", updated_at: "2012-03-15 22:34:39", primary_account_id: nil>
>> u.primary_account
  Account Load (0.1ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."user_id" = 1 LIMIT 1
=> #<Account id: 5, name: "XXXXXX", created_at: "2012-03-16 04:08:33", updated_at: "2012-03-16 17:57:53", user_id: 1>
>> 
Community
  • 1
  • 1
jasonlfunk
  • 5,159
  • 4
  • 29
  • 39
  • 1
    Possibly: `has_one :primary_account, :class_name => "Account", :conditions => "users.primary_account_id = accounts.id"`. – Zabba Mar 26 '12 at 01:03
  • Good guess, but no: `Account Load (0.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."user_id" = 1 AND (users.primary_account_id = accounts.id) LIMIT 1 SQLite3::SQLException: no such column: users.primary_account_id: SELECT "accounts".* FROM "accounts" WHERE "accounts"."user_id" = 1 AND (users.primary_account_id = accounts.id) LIMIT 1` – jasonlfunk Mar 26 '12 at 01:10

1 Answers1

6

So I created a simple ERD and your issue is very simple, but I think I found a serious issue:

simple erd

class User < ActiveRecord::Base
   has_many :accounts
   has_one :primary_account, :class_name => "Account", :primary_key => "account_pimary_id"
end

class Account < ActiveRecord::Base
   belongs_to :user
end

To get the associations as is, just set the :primary_key on has_one :primary_account so that it uses users.account_primary_id instead of users.id.

While this works, it will proboably cause nothing but problems. If Account's user_id is used as the foreign key for id and account_primary_id, you have no idea if an Account is a normal Account or a Primary Account without explicitly joining both id and account_primary_id every time. A foreign_key should only point at 1 column, in this case, User's table id. Then it is a straight shot into the Account's table.

@Zabba solution is the smart one, but just needs the :include for the join

has_one :primary_account, :class_name => "Account", :conditions => "users.primary_account_id = accounts.id", :include => :user

This means all Accounts belong to a User and only 1 is flagged as a primary account. Nice and straight forward, avoiding the wacky where clauses.

mguymon
  • 8,946
  • 2
  • 39
  • 61