Laravel一对多插入

9
我有两个模型:UserRoles。我需要从同一个表单中插入User及其Roles
$user = new User;
$user ->name = $request ->input('name');
$user ->email = $request ->input ('email');
$user -> password = $request ->input ('pass');
$user ->save();
$role = new Role;
$role ->name = $request ->input('role');
$role ->explain = $request ->input('exp');
$role ->save();
$role ->roles() ->save($user);

它给我报错了。

User 模型:

public function roles()
{
    # code...
    return $this ->hasMany('App\Role');
}

角色模型:

public function users()
{
    # code...
    return $this ->belongsTo('App\User');
}

迁移:

   Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password', 60);
        $table->rememberToken();
        $table->timestamps();
    });
    Schema::create('roles', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->unsigned()->index();
        $table->text('name');
        $table->string('explain');
        $table->timestamps();
        //cascade
        $table->foreign('user_id')->references('id')->on('users')-    >onDelete('cascade');
    });

我认为如果关系处理得当,那就没问题了。

你卡在哪里了? - Box Box Box Box
SQLSTATE[23000]: 完整性约束冲突: 1452 无法添加或更新子行: 外键约束失败 (many.roles, CONSTRAINT roles_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE) (SQL: insert into roles (name, explain, updated_at, created_at) values (sss, asw, 2016-02-21 07:34:02, 2016-02-21 07:34:02)) - user5565240
这是一个错误,并且只将其插入到用户表中。 - user5565240
1
如果一个角色只属于一个用户,你应该考虑将方法从“users()”更改为“user()”……这只是一个建议,而不是解决问题的方法。 - tam5
实际上,我收回之前的话,因为Patricus说这确实是解决您问题的一部分。 - tam5
2个回答

14

你的问题在于在关联用户之前保存了 Role。由于你没有将其关联到用户,因此你的 roles.user_id 字段为空,违反了你的外键约束。

你需要修改你的代码,在保存角色之前先关联用户,如下所示:

// create the user
$user = new User;
$user->name = $request->input('name');
$user->email = $request->input ('email');
$user->password = $request->input ('pass');
$user->save();

$role = new Role;
$role->name = $request->input('role');
$role->explain = $request->input('exp');

// option 1:
// this will set the user_id on the role, and then save the role to the db
$user->roles()->save($role);

// option 2:
// associate the user to the role (sets the user_id field)
// then you need to save your role
$role->users()->associate($user);
$role->save();

使用选项1或选项2,不要同时使用。

编辑

另外,当未传入belongsTo关系时,它将根据关系函数的名称构建外键。由于您的方法名为users,因此它将查找users_id字段,这是不正确的。您需要将正确的外键名称作为第二个参数传递,或将关系方法从users()重命名为user()

// option 1
// pass in the foreign key field as the second parameter
public function users()
{
    return $this->belongsTo('App\User', 'user_id');
}

// option 2
// rename the relationship to user
public function user()
{
    return $this->belongsTo('App\User');
}

你可以两个都做,但至少,如果你把方法重命名为user()的话,代码会更加合乎逻辑。


列未找到:1054在“字段列表”中未知的列'users_id'(SQL:insert into roles (name, explain, users_id, updated_at, created_at) values (admin, an admin, 13, 2016-02-21 13:58:19, 2016-02-21 13:58:19)) - user5565240
为什么找不到用户ID? - user5565240
@user5565240 根据您展示的关系,这并没有意义。这是一对多还是多对多的关系?您能否更新您的问题并附上表格定义? - patricus
你刚刚复制粘贴的错误提示说它期望一个字段名为 'users_id',你确定你没有打错字吗?请检查一下你的代码中是否有 'user_id' 而不是 'users_id'。 - tam5

3
这个错误是因为您没有在角色表中传递user_id。它是该表中的外键,必须传递。 您可以通过以下方式保存您的一对多关系表:

https://laravel.com/docs/4.2/eloquent#inserting-related-models

首先,您需要保存主表用户行,然后使用find()方法,您可以保存角色表中的所有详细信息行,就像链接示例一样。
$role = new Role(array('','','','')); // array of roles row values you want save
$user = User::find(1); // where 1 is id
$role = $user->roles()->save($role );

我需要同时添加它们。 - user5565240
好的,您可以通过以下方式获取用户表中插入后的最后一个ID:$user_id = DB :: Query('SELECT LAST_INSERT_ID()'); 然后在find函数中使用它或将其传递给角色,如下所示:$role->user_id = $user_id; 如果您使用自己的代码。 - Gouda Elalfy
@user5565240 你的意思是同时添加它们吗? - tam5
1
我的意思是需要从一个表单中插入所有数据并提交按钮。 - user5565240

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接