【问题标题】:Rails 4, specify custom foreign key in has_many through join table?Rails 4,通过连接表在has_many中指定自定义外键?
【发布时间】:2016-07-20 01:13:48
【问题描述】:

我想在我的 rails 4 应用程序中为 has_many through 关联在连接表中指定一个自定义外键。请看下面,我到目前为止...

当我在 Rails 控制台中执行 user.team_memberships.create 时,我收到此错误:

ActiveRecord::UnknownAttributeError: unknown attribute 'user_id' for TeamMembership.

users.rb

class User < ActiveRecord::Base
    has_many :team_memberships
    has_many :teams, through: :team_memberships

teams.rb

class Team < ActiveRecord::Base
    has_many :team_memberships
    has_many :members, through: :team_memberships

team_membership.rb

    class TeamMembership < ActiveRecord::Base
      belongs_to :member, class_name: 'User', foreign_key: 'member_id'
      belongs_to :team

schema.rb

create_table "team_memberships", force: :cascade do |t|
    t.integer  "member_id"
    t.integer  "team_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  add_index "team_memberships", ["member_id"], name: "index_team_memberships_on_member_id", using: :btree
  add_index "team_memberships", ["team_id"], name: "index_team_memberships_on_team_id", using: :btree

  create_table "teams", force: :cascade do |t|
    t.string   "name"
    t.integer  "team_snap_id"
    t.datetime "created_at",   null: false
    t.datetime "updated_at",   null: false
  end

  create_table "users", force: :cascade 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.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "name"
    t.integer  "teamsnap_uid"
    t.string   "teamsnap_access_token"
  end

【问题讨论】:

  • 当您在UserTeam 上将foreign_key 添加到has_many :through 关系时发生了什么?

标签: ruby-on-rails foreign-keys associations has-many-through


【解决方案1】:

您需要将foreign_key: 'member_id' 添加到User 上的has_many 声明中。您还可以删除TeamMembershipbelongs_to 上的foreign_key 选项——Rails 会自动推断。

用户.rb

class User < ActiveRecord::Base
  has_many :team_memberships, foreign_key: 'member_id'
  has_many :teams, through: :team_memberships

team_membership.rb

class TeamMembership < ActiveRecord::Base
  belongs_to :member, class_name: 'User'
  belongs_to :team

【讨论】:

    【解决方案2】:

    您需要在两个模型中指定外键

    class User < ActiveRecord::Base
      has_many :team_memberships, foreign_key: 'member_id'
      has_many :teams, through: :team_memberships
    end
    

    class TeamMembership < ActiveRecord::Base
      belongs_to :member, class_name: 'User', foreign_key: 'member_id'
      belongs_to :team
    end
    

    如果您没有在用户模型中添加外键,那么您将无法为用户创建团队成员,同样如果您不在团队成员中指定外键,那么您将无法获得团队成员的用户。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 2013-08-01
      相关资源
      最近更新 更多