目标:用户可以创建用户帐户(设计),然后创建一个组。每个用户只有belongs_to
一个组和一个组has_many
用户。
创建并运行迁移后 - 如果我尝试创建用户,则会出现以下错误:“1错误禁止此用户被保存:组必须存在”。
显然,当前设置需要在创建用户时存在group_id。
@group.user_id = current_user.id
中设置GroupsController#create
是否适合将创建用户分配给群组?我尝试在群组模型中使用回调来执行此操作,但我无法访问current_user
变量。unique => true
实现的吗?
class Group < ApplicationRecord
has_many :users
validates :users, presence: true
end
class User < ApplicationRecord
...
belongs_to :group
...
end
class GroupsController < ApplicationController
...
def create
@group = Group.new(group_params)
@group.user_id = current_user.id
...
end
...
private
...
def group_params
params.require(:group).permit(:name, :user_id)
end
...
end
class AddGroupReferenceToUser < ActiveRecord::Migration[5.0]
def change
add_reference :users, :group, foreign_key: true
end
end
class AddUserReferenceToGroup < ActiveRecord::Migration[5.0]
def change
add_reference :groups, :user, foreign_key: true
end
end
ActiveRecord::Schema.define(version: 20160903125553) do
create_table "groups", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.index ["user_id"], name: "index_groups_on_user_id"
end
create_table "users", force: :cascade do |t|
...
t.integer "group_id"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["group_id"], name: "index_users_on_group_id"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
答案 0 :(得分:0)
- 这种情况的belongs_to / has_many关联是否正确?这应该是一个has_one吗?
醇>
要设置用户只能属于单个群组但群组拥有多个用户的关系,那么您就是在正确的轨道上。
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
belongs_to
将外键列设为users.group_id
。使用has_one
会将其放在groups.user_id
列上,该列只允许一对一映射 - 一个组只能拥有一个用户。
- 两个迁移都应该具有外键属性吗?
醇>
否 - 只有users
表应包含外键。应删除AddUserReferenceToGroup
,或者如果您已将其推送到生产状态,则应编写另一个删除groups.user_id
列的迁移。
- 在
醇>@group.user_id = current_user.id
中设置GroupsController#create
是指定创建用户的合适方式 到小组?
否 - 由于group_id
列位于users
列,您需要更新用户表,而不是组。
if @group.save
current_user.update(group: @group)
end
- 我还想强制(在数据库级别)用户只能属于一个组 - 这是使用unique =&gt;实现的吗?架构中是真的吗?
醇>
否 - 由于users
表上的一行只能在groups_id
列中有一个ID,因此用户只能属于一个组。使用unique => true
会在users.groups_id
列上创建唯一性索引,该索引只允许单个用户与某个组关联。
- 如何强制(在数据库级别)组必须拥有用户?
醇>
这实际上是不可能的。要将用户与组关联,必须先将该组插入数据库,以便为其分配ID。
在软件级别添加验证还会产生“鸡与鸡蛋”的情况,其中一个群组无法生效,因为它没有用户且用户无法与群组关联,因为它不会保留。
但是,您可以通过将外键列声明为belongs_to
来在NOT NULL
端设置约束。