RobeeZ
RobeeZ

Reputation: 95

Rails - multiple association unknown attribute

I'm making an API in Rails, and has a Model called Match which has 2 association to the User model defined as

belongs_to :user_a, class_name: 'User', foreign_key: 'user_a'
belongs_to :user_b, class_name: 'User', foreign_key: 'user_b'

In User model:

has_many :matches

In my Match controller spec, I'm doing the following:

before(:each) do
    user = FactoryGirl.create :user
    api_authorization_header user.auth_token
    @match_attribs = FactoryGirl.attributes_for :match
    post :create, { match: @match_attribs }
end

and the tests fails with "unknown attribute: user_id"

If I make the change to post:

post :create, { user_a: user.id, user_b: user.id, match: @match_attribs }

then its still giving me unknown attribute.

Edit: scheme for matches:

create_table "matches", force: true do |t|
    t.integer  "user_a"
    t.integer  "user_b"
    t.datetime "created_at"
    t.datetime "updated_at"
end

add_index "matches", ["user_a"], name: "index_matches_on_user_a"
add_index "matches", ["user_b"], name: "index_matches_on_user_b"

Thanks for any help

Upvotes: 0

Views: 255

Answers (2)

eirikir
eirikir

Reputation: 3842

Rails and SQL convention dictate that foreign keys should end in _id, e.g. user_a_id, user_b_id. Since Rails is built around "convention over configuration," convention will make your code simpler. If you change the field names, the code becomes:

match.rb

belongs_to :user_a, class_name: "User"
belongs_to :user_b, class_name: "User"

user.rb

has_many :matches_a, class_name: 'Match', foreign_key: 'user_a_id'
has_many :matches_b, class_name: 'Match', foreign_key: 'user_b_id'

def matches
  Match.where("user_a_id = :id OR user_b_id = :id", id: id)
end

Using a method is the only way to make this kind of relation. This way will return a relation that you can further query, while simply concatenating the other two relations (matches_a + matches_b) will return an array.

Upvotes: 1

katafrakt
katafrakt

Reputation: 2488

The only way I know how to make it work with your schema is to put in user model:

has_many :matches_as_a, foreign_key: 'user_a'
has_many :matches_as_b, foreign_key: 'user_b'

def matches
  matches_as_a + matches_as_b
end

If there is another way, I'd be glad to know it and refactor some of my apps (not including join models, of course) ;)

Upvotes: 1

Related Questions