多对多:NameError异常

时间:2014-01-13 13:27:38

标签: ruby-on-rails

我有以下型号:

group.rb:

class Group < ActiveRecord::Base
  has_many :users_groups
  has_many :users, through: :users_groups
end

user.rb:

class User < ActiveRecord::Base
  has_many :users_groups
  has_many :groups, through: :users_groups
end

users_groups.rb

class UsersGroups < ActiveRecord::Base
    belongs_to :user
    belongs_to :group
end

当我在Rails'控制台中键入@group.users时,它会抛出错误:

NameError: uninitialized constant Group::UsersGroup

当我在users_groups.rb中将UsersGroups更改为UsersGroup时,我仍然会遇到同样的错误。

我正在使用Rails 4.0.2。这是一个错误吗?

4 个答案:

答案 0 :(得分:1)

不,这不是错误。你没有遵循惯例。模型必须是单数,但您使用复数UsersGroups。如果您将型号名称更改为UsersGroup,则可能会有效。

答案 1 :(得分:1)

如果您尝试在两个表之间创建HABTM,则不需要介体模型。根据惯例,表格应该是名称groups_users,按字母顺序排在第一位的表格应该在表格名称中排在第一位。访问http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association

答案 2 :(得分:1)

这可能是因为rails希望您遵循其命名约定,例如,这意味着模型名称应该是单数。

如果您要为连接表/模型命名UserGroup(或UsersGroup),它可能会起作用,如下所示:

class Group < ActiveRecord::Base
  has_many :user_groups
  has_many :users, through: :user_groups
end

class User < ActiveRecord::Base
  has_many :user_groups
  has_many :groups, through: :user_groups
end

class UserGroup < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

另外,正如有人已经指出的那样,你并不需要一个中介模型。你可以让rails自动创建连接表。我确实建议你自己实际创建一个中介表/模型。如果你这样做,知道发生了什么事情会更清楚。

答案 3 :(得分:1)

如果UsersGroups除了提供HABTM(没有回调,验证或自定义属性)之外没有逻辑,您可以删除该类并以这种方式替换关系:

class Group < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups
end

并且必须将联接表称为groups_users作为&#39; groups&#39;首先是用户&#39;按字母顺序

create_table :groups_users do |t|
  t.belongs_to :group
  t.belongs_to :user
end

如果您打算使用某种逻辑,并且需要一个类,则可以使用has_many :through。在那里你可以毫无问题地调用连接表UserGroup

class Group < ActiveRecord::Base
  has_many :user_groups
  has_many :users, through: :user_groups
end

class User < ActiveRecord::Base
  has_many :user_groups
  has_many :groups, through: :user_groups
end

class UserGroup < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end