【问题标题】:Ruby on Rails Relationship between 3 modelsRuby on Rails 3 模型之间的关系
【发布时间】:2013-02-22 23:11:45
【问题描述】:

我正在关注为 Rails 3 制作的教程,我正在使用 Rails 3.2,但我认为我正确地遵循它但出现错误,我的课程如下,当我使用 task.admin_users_tasks 时发生错误

class Task < ActiveRecord::Base

  attr_accessible :name, :project_id, :task_id, :permalink, :visible, :position, :created_at
  belongs_to :project
  has_and_belongs_to_many :admin_users
  has_many :admin_users_tasks
end

class AdminUsersTask < ActiveRecord::Base
  attr_accessible :admin_user_id, :task_id, :created_at, :updated_at
  belongs_to :admin_user, :class_name => "AdminUser" :foreign_key => 'admin_user_id'
  belongs_to :task
end

class AdminUser < ActiveRecord::Base

  attr_accessible :first_name, :last_name, :username, :email

  has_and_belongs_to_many :projects
  has_and_belongs_to_many :tasks
  has_many :admin_users_tasks
  has_many :admin_users_projects
end

Rails 控制台

    1.9.3-p362 :032 > task
 => #<Task id: 1, project_id: 6, permalink: "taskytask", position: 1, visible: true,   created_at: "2013-02-21 05:08:01", updated_at: "2013-02-21 05:08:01", name: "Task Name for   Noname Project"> 
1.9.3-p362 :033 > me
 => #<AdminUser id: 1, first_name: "Larry", last_name: "David", email:         "larry.david@mail.com", hashed_password: "c9f4e8d3aaa265033c2f517abd5d347bd81d67fa",     created_at: "2013-02-21 04:43:20", updated_at: "2013-02-21 04:43:20", username: "larrydavid",     salt: "d4189f8db685776d3a3c3c4d0700786b7879362d"> 
1.9.3-p362 :034 > me.admin_users_tasks
 => [] 
1.9.3-p362 :035 > task.admin_users_tasks
NoMethodError: undefined method `admin_users_tasks' for #<Task:0x007fca9e159f58>
    from /Users/larrydavid/.rvm/gems/ruby-1.9.3-p362/gems/activemodel-    3.2.11/lib/active_model/attribute_methods.rb:407:in `method_missing'
    from /Users/larrydavid/.rvm/gems/ruby-1.9.3-p362/gems/activerecord-    3.2.11/lib/active_record/attribute_methods.rb:149:in `method_missing'
    from (irb):35
        from /Users/larrydavid/.rvm/gems/ruby-1.9.3-p362/gems/railties-    3.2.11/lib/rails/commands/console.rb:47:in `start'
    from /Users/larrydavid/.rvm/gems/ruby-1.9.3-p362/gems/railties-    3.2.11/lib/rails/commands/console.rb:8:in `start'
    from /Users/larrydavid/.rvm/gems/ruby-1.9.3-p362/gems/railties-    3.2.11/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
from script/rails:6:in `<main>'
1.9.3-p362 :036 > 

【问题讨论】:

  • 在添加 has_many :admin_users_tasks 关联后,您是否重新启动了您的 Rails 控制台?
  • 谢谢,我还没有重新启动我的控制台。
  • 控制台还有一个reload 命令,通常可以解决问题。

标签: mysql ruby-on-rails ruby-on-rails-3.2 relationship rails-activerecord


【解决方案1】:

该代码有点尴尬,主要是因为您使用 HABTM 语法以及提供模型,您应该使用 has_many :through 来完成。我会以不同的方式设置模型,然后 rails 可能不会那么混乱。

class Task < ActiveRecord::Base
  has_many :admin_users_tasks
  has_many :admin_users, :through => :admin_users_tasks
end

class AdminUser < ActiveRecord::Base
  has_many :admin_users_tasks
  has_many :tasks, :through => :admin_users_tasks
end

class AdminUserTasks < ActiveRecord::Base
  belongs_to :admin_user
  belongs_to :task
end

HABTM 适用于您需要多对多连接的情况,并且您没有连接表的模型,连接的每一侧只有 2 列。没有 ID 或时间戳。

has_many :through 用于当你想要一个多对多连接时,连接表有一个模型,使其实际上是一个双多对一连接,连接表有一个 id 列,时间戳,以及两个外键。

此外,从您的代码外观来看,您对 AdminUser 和 Project 做同样的事情,如果有一个 AdminUserProject 模型加入这两个模型,请使用 has_many :through not HABTM。

【讨论】:

  • 感谢您的信息,我必须申请。试图理解所有这些关系和类型是很困难的。
  • 一开始可能是这样,一旦你习惯了这些约定,它就会变得更有意义。祝你好运:)
【解决方案2】:

解决了这个问题。首先控制台没有重启。

其次,在 Rails 3.2 中,

belongs_to :admin_user, :class_name => "AdminUser" :foreign_key => 'admin_user_id'

应该是

belongs_to :admin_user, class_name: "AdminUser", foreign_key: 'admin_user_id'

【讨论】:

  • 其实两者都有效,第一行是Ruby中普通的hash语法,第二行是Ruby 1.9较新的语法,但是只有当你有键的符号时才有效,你需要第一行与任何其他键类型。
  • 啊,好吧,没想到你不能把它们混在一起!有道理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
相关资源
最近更新 更多