No such column when creating an alias for a model association in Rails

278 views Asked by At

I want to create a one to many association between a User and Task model. In my user model I'd like to give it the alias of owner and refer to the user's tasks as owned_tasks.

class User < ActiveRecord::Base
    has_many :owned_tasks, class_name: "Task", as: :owner
end

class Task < ActiveRecord::Base
    #owner_id
    belongs_to :owner, class_name: "User"
end

When I try and retrieve the list of tasks as so I run into this error:

user = User.first
user.owned_tasks

SQLite3::SQLException: no such column: tasks.owner_type: SELECT "tasks".* FROM "tasks" WHERE "tasks"."owner_id" = ? AND "tasks"."owner_type" = ?
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: tasks.owner_type: SELECT "tasks".* FROM "tasks" WHERE "tasks"."owner_id" = ? AND "tasks"."owner_type" = ?

Why is it referring to owner_type when there's no attribute of that name stored in my database?

2

There are 2 answers

1
Arup Rakshit On BEST ANSWER

Here is your corrected version :

class User < ActiveRecord::Base
    has_many :owned_tasks, class_name: "Task", foreign_key: :owner_id
end

class Task < ActiveRecord::Base
    #owner_id
    belongs_to :owner, class_name: "User"
end

Why need :foreign_key option ?

Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and _id suffixed. So a Person class that makes a has_many association will use person_id as the default :foreign_key.

Specify the foreign key used for the association. By default this is guessed to be the name of the association with an _id suffix. So a class that defines a belongs_to :person association will use person_id as the default :foreign_key. Similarly, belongs_to :favorite_person, class_name: "Person" will use a foreign key of favorite_person_id.

0
max On

In Rails the :as option is used when setting up polymorphic relationships. In a polymorphic relationship the other can be several different models. That's why the tasks.owner_type column is required - it tells Rails which table to look at when loading the owner relation.

The solution is to either create a tasks.owner_type column or to setup the relationship as follows:

class User < ActiveRecord::Base
    has_many :owned_tasks, 
             class_name: "Task", 
             foreign_key: :owner_id
end

class Task < ActiveRecord::Base
    belongs_to :owner, class_name: "User"
end