Rails 4,通过连接表在has_many中指定自定义外键?
Posted
技术标签:
【中文标题】Rails 4,通过连接表在has_many中指定自定义外键?【英文标题】:Rails 4, specify custom foreign key in has_many through join table? 【发布时间】: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
【问题讨论】:
当您在User
和Team
上将foreign_key 添加到has_many :through
关系时发生了什么?
【参考方案1】:
您需要将foreign_key: 'member_id'
添加到User
上的has_many
声明中。您还可以删除TeamMembership
中belongs_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
如果您没有在用户模型中添加外键,那么您将无法为用户创建团队成员,同样如果您不在团队成员中指定外键,那么您将无法获得团队成员的用户。
【讨论】:
以上是关于Rails 4,通过连接表在has_many中指定自定义外键?的主要内容,如果未能解决你的问题,请参考以下文章
带有has_many的Rails嵌套表单:通过,如何编辑连接模型的属性?