Jonny B
Jonny B

Reputation: 720

has_one association not adding methods to belongs_to class

I have two tables User and UserToken. User has_one: token and UserToken belongs_to :user. I was under the impression this would add UserToken#User method to the UserToken class. However, I am getting:

undefined method 'user' for '#' with the following 'UserToken.where(user_id: 1).user

Do I not understand the association correctly or have I not set it up right?

UsersController:

  def get
    user = UserToken.where(user_id: 1).user

    render json: user.to_json
  end

User Model:

class User < ApplicationRecord
  has_one :user_token
end

UserToken Model:

class UserToken < ApplicationRecord
  belongs_to :user
end

Migration:

    def change
        create_table :users do |t|
      # This id comes from Auth0
      t.datetime :date
      t.timestamp :updated_at
      t.timestamp :created_at
    end

    create_table :user_tokens do |t|
      t.belongs_to :user
      # This comes from plaid when a user signs in
      t.string :token
      t.timestamp :updated_at
      t.timestamp :created_at
    end
  end

Schema:

ActiveRecord::Schema.define(version: 2019_09_19_004350) do

  create_table "user_tokens", force: :cascade do |t|
    t.bigint "user_id"
    t.string "token"
    t.datetime "updated_at"
    t.datetime "created_at"
    t.index ["user_id"], name: "index_user_tokens_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.datetime "date"
    t.datetime "updated_at"
    t.datetime "created_at"
  end
end

Upvotes: 1

Views: 47

Answers (1)

Viktor
Viktor

Reputation: 2773

What you want is:

UserToken.where(user_id: 1).first.user

or better yet:

UserToken.find_by(user_id: 1).user

You're getting the "undefined method" error because #where returns an ActiveRecord::Relation and an ActiveRecord Relation has no #user method.

UserToken.where(user_id: 1).class.name
#=> "ActiveRecord::Relation"
UserToken.where(user_id: 1).first.class.name
#=> "UserToken"

Upvotes: 1

Related Questions