【问题标题】:Rails creating a M:M relationshipRails 创建 M:M 关系
【发布时间】:2017-05-22 02:24:22
【问题描述】:

我有一个用户模型和一个成员模型加入的团队模型。

一个用户可以有多个团队,每个团队可以有多个用户等。

class User < ApplicationRecord
  has_many :memberships
  has_many :teams, through: :memberships
End

class Team < ApplicationRecord
  has_many :memberships
  has_many :users, through: :memberships
End

class Membership < ApplicationRecord
  belongs_to :user
  belongs_to :team
end

我正在寻找一种方法来简单地创建会员记录,但是我缺少一些东西:

2.4.0 :026 > t = Team.last
  Team Load (1.2ms)  SELECT  "teams".* FROM "teams" ORDER BY "teams"."id" DESC LIMIT $1  [["LIMIT", 1]]
 => #<Team id: 42129, name: "Reds", description: "A good team", created_at: "2017-05-18 05:05:09", updated_at: "2017-05-18 05:05:09"> 
2.4.0 :027 > User.first.memberships
  User Load (1.7ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
  Membership Load (1.1ms)  SELECT  "memberships".* FROM "memberships" WHERE "memberships"."user_id" = $1 LIMIT $2  [["user_id", 1], ["LIMIT", 11]]
 => #<ActiveRecord::Associations::CollectionProxy []> 
2.4.0 :028 > User.first.memberships << t
  User Load (0.8ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
   (0.4ms)  BEGIN
   (0.4ms)  ROLLBACK
ActiveRecord::AssociationTypeMismatch: Membership(#23507760) expected, got #<Team id: 42129, name: "Reds", description: "A good team", created_at: "2017-05-18 05:05:09", updated_at: "2017-05-18 05:05:09"> which is an instance of Team(#33684520)
    from (irb):28
2.4.0 :029 > 

我在这里错过了什么?

更新: 当我创建新的会员记录并手动添加 fk 值时,我在尝试保存时收到此错误:

2.4.0 :037 > m
 => #<Membership id: nil, user_id: 1, team_id: 22641, created_at: nil, updated_at: nil> 
2.4.0 :038 > m.save
   (0.5ms)  BEGIN
   (0.4ms)  ROLLBACK
NoMethodError: undefined method `class_name' for nil:NilClass
Did you mean?  class_eval
    from (irb):38

更新2

2.4.0 :022 > user = User.first
  User Load (2.7ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
 => #<User id: 1, created_at: "2017-05-15 08:17:01", updated_at: "2017-05-19 02:54:30"> 
2.4.0 :023 > team = Team.first
  Team Load (2.3ms)  SELECT  "teams".* FROM "teams" ORDER BY "teams"."id" ASC LIMIT $1  [["LIMIT", 1]]
 => #<Team id: 22641, name: "Reds", description: "This is a good team", created_at: "2017-05-18 01:41:00", updated_at: "2017-05-18 05:05:09"> 

2.4.0 :027 > Membership.delete_all
  SQL (1.9ms)  DELETE FROM "memberships"
 => 1 
2.4.0 :029 > m=Membership.new(user: user, team: team)
 => #<Membership id: nil, user_id: 1, team_id: 22641, created_at: nil, updated_at: nil> 
2.4.0 :031 > m.save
   (1.0ms)  BEGIN
  SQL (2.3ms)  INSERT INTO "memberships" ("user_id", "team_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["user_id", 1], ["team_id", 22641], ["created_at", "2017-05-22 03:37:22.803718"], ["updated_at", "2017-05-22 03:37:22.803718"]]
   (2.1ms)  COMMIT
 => true 

2.4.0 :032 > Membership.delete_all
  SQL (1.9ms)  DELETE FROM "memberships"
 => 1 
2.4.0 :033 > m=Membership.new
 => #<Membership id: nil, user_id: nil, team_id: nil, created_at: nil, updated_at: nil> 
2.4.0 :034 > m.user_id=user.id
 => 1 
2.4.0 :035 > m.team_id=team.id
 => 22641 
2.4.0 :036 > m
 => #<Membership id: nil, user_id: 1, team_id: 22641, created_at: nil, updated_at: nil> 
2.4.0 :037 > m.save
   (0.5ms)  BEGIN
  User Load (0.9ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.8ms)  ROLLBACK
NoMethodError: undefined method `class_name' for nil:NilClass
Did you mean?  class_eval
    from (irb):37

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    您收到的第一条错误消息(在更新之前)是因为 ActiveRecord 需要一个 Membership 的实例,而它正在收到一个 TeamUser.first.teams &lt;&lt; t 应该适用于该示例。

    至于您在更新中分享的错误,我在尝试时没有遇到,而且它似乎与您提供的关系很好。

    2.2.3 :009 > user = User.first
      User Load (0.2ms)  SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1
     => #<User id: 1>
    2.2.3 :010 > team = Team.first
      Team Load (0.2ms)  SELECT  "teams".* FROM "teams"  ORDER BY "teams"."id" ASC LIMIT 1
     => #<Team id: 1>
    2.2.3 :011 > membership = Membership.new(user: user, team: team)
     => #<Membership id: nil, user_id: 1, team_id: 1>
    2.2.3 :012 > membership.save
       (0.1ms)  begin transaction
      SQL (1.2ms)  INSERT INTO "memberships" ("user_id", "team_id") VALUES (?, ?)  [["user_id", 1], ["team_id", 1]]
       (2.3ms)  commit transaction
     => true
    

    要仔细检查的一件事是您如何构建 Membership 记录,并且模型中没有复数错误。将实际的 UserTeam 实例传递给 Membership.newMembership.create 应该可以工作。

    【讨论】:

    • 谢谢,因为这回答了问题一。 Update2 对我来说毫无意义。
    猜你喜欢
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    相关资源
    最近更新 更多