为什么这个ActiveRecord关系不起作用?

时间:2014-01-10 20:34:43

标签: ruby-on-rails

当我尝试访问Users类的'groups'或'members'属性时,我得到了成员的未定义方法错误。 (注意:我知道我需要将我的成员类重新定义为单数,这是次要的,以便弄清楚为什么它会被打破)

我有一个用户类如下:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  has_many :group, :through => :member
end

会员班:

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

小组课程:

class Group < ActiveRecord::Base
    has_many :users, :through => :members
end

包含以下内容的架构:

create_table "groups", force: true do |t|
  t.string   "group_name"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "members", force: true do |t|
  t.integer  "group_id"
  t.integer  "user_id"
  t.datetime "created_at"
  t.datetime "updated_at"
end

add_index "members", ["group_id"], name: "index_members_on_group_id"
add_index "members", ["user_id"], name: "index_members_on_user_id"

create_table "users", force: true do |t|
  t.string   "email",                  default: "",     null: false
  t.string   "encrypted_password",     default: "",     null: false
  t.string   "reset_password_token"
  t.datetime "reset_password_sent_at"
  t.datetime "remember_created_at"
  t.integer  "sign_in_count",          default: 0,      null: false
  t.datetime "current_sign_in_at"
  t.datetime "last_sign_in_at"
  t.string   "current_sign_in_ip"
  t.string   "last_sign_in_ip"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "role",                   default: "user"
end

add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

1 个答案:

答案 0 :(得分:3)

您的has_manyUser模型中的联接模型缺少Group

has_many :members添加到UserGroup模型类定义中:

用户模型:

class User < ActiveRecord::Base
  ...
  has_many :members
  has_many :groups, :through => :members
end

请注意,在User模型中,您有has_many :group, :through => :member。由于您要定义has_many关系,因此您的关联符号也必须是复数。

群组模型:

class Group < ActiveRecord::Base
    has_many :members
    has_many :users, :through => :members
end

使用class_name选项 ,如果您想保留Members班级名称Members(复数):

是的,您应该考虑按照惯例将Members模型重命名为Member。但是,如果您仍希望将其保留为复数或任何其他名称,则可以在class_name声明中指定has_many选项,以便正确映射到类名称的符号。因此,您的UserGroup模型需要更新为:

用户模型:

class User < ActiveRecord::Base
  ...
  has_many :members, class_name: 'Members'
  has_many :groups, :through => :members
end

群组模型:

class Group < ActiveRecord::Base
    has_many :members, class_name: 'Members'
    has_many :users, :through => :members
end