【问题标题】:Rails not loading referencial attributeRails 未加载参考属性
【发布时间】:2014-08-10 01:29:02
【问题描述】:

我有两个模型,用户和角色。我添加了一个如下所示的迁移:

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

现在我的架构如下所示:

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

我的模型是这样的:

class Role < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_one :role
end

在我的 seed.rb 中,我正在尝试做:

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

我收到以下错误:

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)

当我在模型中明确说明了关系后,为什么还要为角色中的用户寻找外键?

【问题讨论】:

    标签: mysql ruby-on-rails models database-migration


    【解决方案1】:

    当您在 Rails 中使用 belongs_to 时,您是在说包含 belongs_to 的模型具有另一个对象的外键。在本例中,您已将外键 role_id 放置在 User 模型上。因此,User 模型应包含belongs_to :roleRole 模型应包含has_many :users

    【讨论】:

    • 好吧,我现在看到了这个错误,尽管按字典顺序对我来说更有意义的是相反。我现在得到: NoMethodError: undefined method ` 在我改变了关系之后
    • super_role = Role.find_by_name('Super Admin') print super_role.name user.role
    • user.role 不是数组。它适用于单个对象。将user.role &lt;&lt; super_role 更改为user.role = super_role。您构建模型的方式是用户只能属于一个角色。
    • 太棒了。非常感谢 Sean 和 Carlos 的所有帮助。
    • 我认为这工作正常,因为我不再收到错误,但我发现它实际上并没有设置角色 ID。当我执行 user.role = super_role Unresolved Ruby Reference 时出现警告
    【解决方案2】:

    那是因为你使用 has_one 和 belongs_to 相反。

    您的模型应如下所示:

    class Role < ActiveRecord::Base
      has_one :user
    end
    
    class User < ActiveRecord::Base
      belongs_to :role
    end
    

    【讨论】:

    • 如果他在Role 模型上使用has_one :user,那么他将在RoleUser 之间创建一对一的关系。我猜这不是他想要的。通常,角色是以一对多或多对多的方式构建的。
    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多