【问题标题】:Laravel Eloquent Relationships - Integrity constraint violationLaravel Eloquent 关系 - 违反完整性约束
【发布时间】:2016-05-01 14:40:14
【问题描述】:

我有 3 个模型:优先级、任务和用户

优先级

  • 可以分配给许多任务
  • 属于一个用户

代码...

class Priority extends Model
{
    protected $fillable = ['name', 'hexcolorcode'];

    protected $casts = [
        'user_id' => 'int',
    ];

    public function task()
    {
        return $this->hasMany(Task::class);
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

任务

  • 已分配一个优先级
  • 属于一个用户

代码...

class Task extends Model
{
    protected $fillable = ['name'];

    protected $casts = [
        'user_id' => 'int',
    ];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function priority()
    {
        return $this->hasOne(Priority::class);
    }
}

用户

  • 可以有很多任务
  • 可以有很多优先级

代码...

class User extends Authenticatable
{

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    public function tasks()
    {
        return $this->hasMany(Task::class);
    }

    public function priorities()
    {
        return $this->hasMany(Priority::class);
    }
}

任务控制器

class TaskController extends Controller
{
    protected $tasks;

    private $priorities;

    public function __construct(TaskRepository $tasks, PriorityRepository $priorities)
    {
        $this->middleware('auth');
        $this->tasks = $tasks;
        $this->priorities = $priorities;
    }

    public function index(Request $request)
    {
        return view('tasks.index', [
            'tasks' => $this->tasks->forUser($request->user()),
            'priorities' => $this->priorities->forUser($request->user())
        ]);
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|max:255',
            'description' => 'required',
            'priority' => 'required'
        ]);

        $request->user()->tasks()->create([
            'name' => $request->name,
            'description' => $request->description,
            'priority_id' => $request->priority
        ]);

        return redirect('/tasks');
    }

    public function edit(Task $task)
    {
        $this->authorize('edit', $task);

        return view('tasks.edit', compact('task'));
    }

    public function update(Request $request, Task $task)
    {
        $this->validate($request, [
            'name' => 'required|max:255',
        ]);

        $task->update($request->all());
        return redirect('/tasks');
    }

    public function destroy(Request $request, Task $task)
    {
        $this->authorize('destroy', $task);

        $task->delete();

        return redirect('/tasks');
    }
}

错误

现在当我想存储一个任务时,它给了我以下错误:

SQLSTATE[23000]:违反完整性约束:1452 无法添加或 更新子行:外键约束失败(tasks.tasks, 约束 tasks_priority_id_foreign 外键 (priority_id) 参考priorities (id)) (SQL: 插入tasks (name, user_id, updated_at, created_at) 值(测试任务,1, 2016-05-01 14:11:21, 2016-05-01 14:11:21))

这种结构是否可行,还是我必须在优先级表和任务表之间使用多态关系?

我的表格

数据库模型图片:http://picpaste.de/mysql-kBH4tO5T.PNG

class CreatePrioritiesTable extends Migration
{

    public function up()
    {
        Schema::create('priorities', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->char('name');
            $table->char('hexcolorcode', 7);
            $table->timestamps();
            $table->foreign('user_id')->references('id')->on('users');
        });
    }
}


class CreateTasksTable extends Migration
{

    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->string('name');
            $table->text('description');
            $table->integer('priority_id')->unsigned();
            $table->timestamps();
            $table->foreign('priority_id')->references('id')->on('priorities');
            $table->foreign('user_id')->references('id')->on('users');
        });
    }
}

更新

优先级控制器

class PriorityController extends Controller
{

    protected $priorities;

    public function __construct(PriorityRepository $priorities)
    {
        $this->middleware('auth');
        $this->priorities = $priorities;
    }

    public function index(Request $request)
    {
        return view('priority.index', [
            'priorities' => $this->priorities->forUser($request->user()),
        ]);
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|max:255',
            'hexcolorcode' => 'required|max:7'
        ]);

        $request->user()->priorities()->create($request->all());

        return redirect('/priorities');
    }

    public function edit(Priority $priority)
    {
        $this->authorize('edit', $priority);

        return view('priority.edit', compact('priority'));
    }

    public function update(Request $request, Priority $priority)
    {
        $this->validate($request, [
            'name' => 'required|max:255',
            'hexcolorcode' => 'required|max:7'
        ]);

        $priority->update($request->all());
        return redirect('/priorities');
    }

    public function destroy(Request $request, Priority $priority)
    {
        $this->authorize('destroy', $priority);

        $priority->delete();

        return redirect('/priorities');
    }
}

【问题讨论】:

  • 我还检查了您的数据库架构。为什么在优先级表中需要用户 ID?如果我是对的,用户必须对给定任务具有优先级不是吗?您也可以从优先级表中删除用户 ID。所以你有这种方式。一个用户有很多任务,每个任务都有一个优先级。这样即使您需要找出用户有哪些任务或他为给定任务设置的优先级。您可以轻松查询。如果我能很好地理解你的问题
  • 还是每个用户先创建优先级,然后再给任务设置?因为没有创建优先级存储,所以最终会出现外键错误。你想如何解决这个问题。
  • @MurlidharFichadia 是的,用户首先创建一个优先级,然后创建一个分配给它的优先级的任务。

标签: php mysql eloquent laravel-5.2


【解决方案1】:

在您的商店方法中。它说的创建方法:

用户->任务()。该位只会在用户和任务表中插入数据。这就是为什么你有外键错误。由于您没有更新您的表之一(优先级),并且您已经在表中添加了外键,正如我从迁移中看到的那样。

如果您有一个名为 task_user 的数据透视表,其中有用户 ID、任务 ID 和优先级 ID,那么您想要实现的目标是正确的。这将是完美的,因为您只需使用 userid 和 taskid 更新优先级列。这是一种方法,但它需要很少的更改,或者您可以将数据分别插入到用户和任务表中,您只需更改查询即可。你喜欢哪个?我可以给你看一个你喜欢的例子。

    //for Priority
        // store
        $priorities = new Priority;
        $priorities->name       = Input::get('priority_name');
        $priorities->hexcolorcode      = Input::get('hexcolorcode');
        $priorities->save();

        $priority = Priority::select('id')->orderBy('created_at', 'desc')->first();

    //for Task
    $tasks = new Task;
        $tasks->name       = Input::get('task_name');
        $tasks->priority_id      = Input::get('priority');
        $priorities->save();

        // redirect
        return Redirect::to('some view please change this');

请解释视图或显示屏幕截图,您是如何处理的。目前,我已经为您提供了一种解决方案,其中一个控制器可以处理优先级和任务。

【讨论】:

  • 我可以先存储任务然后更新其优先级。非常感谢您的帮助。
  • 好的,我会给你想要的解决方案。
  • 我真的不知道你有什么看法。用户是否在两个不同的视图中有两个不同的表单来创建优先级,然后添加分配了优先级的任务?您目前如何处理视图。
  • 感谢您的建议!是的,用户有两个不同的控制器和两个不同的视图来添加优先级和任务。我用整个 taskController 和 priorityController 更新了我的帖子
  • 我似乎觉得你的控制器很好。您的问题现在解决了吗?
【解决方案2】:

解决方案

我在任务模型内的可填充数组中添加了 priority_id 属性。

protected $fillable = ['name', 'description', 'priority_id'];

我有一个理解问题,因为 user_id 是从框架自动分配的,但它没有在可填充数组中指定。那是因为我说 $request->user->tasks->create();是框架分配的,而priority_id是通过用户分配的,所以是批量分配的,需要在可填充数组中指定。

@Murlidhar Fichadia

【讨论】:

    猜你喜欢
    • 2016-03-16
    • 2019-04-12
    • 2016-08-11
    • 1970-01-01
    • 2019-01-02
    • 2017-09-11
    • 2020-06-14
    • 2016-05-25
    相关资源
    最近更新 更多