Search code examples
mysqlruby-on-railsmodelsdatabase-migration

Rails not loading referencial attribute


I have a two models, User and Role. I added a migration that looks like:

class AddRoleReferenceToUsers < ActiveRecord::Migration
   def change
     add_reference :users, :role, index: true
  end
end

Now my schema looks like this:

create_table "roles", force: true do |t|
  t.string   "name"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "users", force: true do |t|
  t.string   "email",                  default: "", null: false
  t.string   "name"
  t.integer  "role_id"
end
add_index "users", ["role_id"], name: "index_users_on_role_id", using: :btree

And my models like this:

class Role < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_one :role
end

In my seed.rb I am trying to do:

user = User.create(email:"example@example.com" name:"Ben")
<Initialize Role table with some values>
user.role = Role.first

And I am getting the following error:

ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'roles.user_id' in 'where    clause': SELECT  `roles`.* FROM `roles`  WHERE `roles`.`user_id` = 1 LIMIT 1
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:301:in `query'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:301:in `block in execute'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:373:in `block in log'
/Library/Ruby/Gems/2.0.0/gems/activesupport-4.1.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:367:in `log'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:301:in `execute'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/mysql2_adapter.rb:228:in `execute'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/mysql2_adapter.rb:232:in `exec_query'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/mysql2_adapter.rb:240:in `select'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract/database_statements.rb:31:in `select_all'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract/query_cache.rb:69:in `select_all'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/querying.rb:39:in `find_by_sql'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/relation.rb:603:in `exec_queries'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/association_relation.rb:15:in `exec_queries'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/relation.rb:487:in `load'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/relation.rb:231:in `to_a'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/relation/finder_methods.rb:451:in `find_take'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/relation/finder_methods.rb:98:in `take'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/associations/singular_association.rb:42:in `find_target'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/associations/association.rb:138:in `load_target'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/associations/association.rb:53:in `reload'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/associations/singular_association.rb:9:in `reader'
 /Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/associations/builder/association.rb:110:in `role'
/Users/ryancollins/RubymineProjects/StreamBoard/db/seeds.rb:37:in `<top (required)>'
/Library/Ruby/Gems/2.0.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:in `load'
/Library/Ruby/Gems/2.0.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:in `block in load'
/Library/Ruby/Gems/2.0.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:232:in `load_dependency'
/Library/Ruby/Gems/2.0.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:in `load'
/Library/Ruby/Gems/2.0.0/gems/railties-4.1.1/lib/rails/engine.rb:543:in `load_seed'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/tasks/database_tasks.rb:184:in `load_seed'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.1/lib/active_record/railties/databases.rake:173:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:seed
(See full trace by running task with --trace)

Why would it be looking for a foreign key for user in roles when I have clearly stated the relationship in my models?


Solution

  • When you use belongs_to in Rails, you're saying that the model containing the belongs_to has the foreign key to the other object. In this case, you've placed the foreign key, role_id on the User model. Therefore, the User model should contain the belongs_to :role, and the Role model should contain has_many :users.