【问题标题】:Laravel 5 - setting up relationshipsLaravel 5 - 建立关系
【发布时间】:2016-01-07 22:28:31
【问题描述】:

我在申请过程中遇到了一些困难,并问了很多问题,在我继续之前,我只想确保我的人际关系正常。

所以我正在创建一个应用程序,您可以在其中根据您提供的输入生成不同的文档。所以,我创建了一个项目,在该项目中有一个选择字段,其中包含不同类型的文档。例如,如果我选择 DocumentA,则 DocumentA 的创建表单将显示给用户。如果我选择 DocumentB,则会显示 DocumentB 的创建表单。现在,尽管这些表单不同并且接受不同的输入,但我想要一种方法,我不必为每种文档类型创建一个新表。所以我想出了以下内容。

所以在一个项目中,我选择我要创建 DocumentA。然后显示视图 documentA.create。此视图具有文档名称和描述的隐藏输入。表单字段标签是 document_data 表中的键,值是该字段的输入。因此,如果我创建 DocumentA,我的数据库可能如下所示

project

 id | projectName  | 
------------------
 1  | Project One  | 
------------------

document

 id | projectId  | documentName |
--------------------------------
 1  | 1          | DocumentA    |
--------------------------------


document_data

 id | documentId | key         |  value      |  
----------------------------------------------
 1  | 1          | clientName  |  Google     |   
----------------------------------------------
 2  | 1          | projectName |  Analytics  |  
----------------------------------------------
 3  | 1          | Contact     |  Mr Sharp   |  
----------------------------------------------
 4  | 1          | startDate   |  29/12/2016 |  
----------------------------------------------

我现在苦苦挣扎的地方是外键 documentId 在 document_data 表中。但是,只有在我的两个模型类中都设置了外键时,事情才会起作用,例如

class Document extends Model
{
    protected $table = 'documents';
    protected $guarded = [];

    public function documentData()
    {
        return $this->hasMany('App\DocumentData', 'documentId');
    }
}

class DocumentData extends Model
{
    protected $table = 'document_data';
    protected $guarded = [];

    public function document()
    {
        return $this->belongsTo('App\Document', 'documentId');
    }
}

如果我没有在两个类中设置它,我会得到一个 MethodNotAllowedHTTP 异常,没有任何相关信息。我已经能够毫无问题地创建文档,当我需要更新时就会出现问题。 DocumentA 的编辑页面有一个这样开头的表单

{{ $document }}

{!! Form::model($project->document, [
    'class'=>'form-horizontal',
    'method' => 'PATCH',
    'route' => ['projects.documents.update', $project, $project->document]
]) !!}

现在,当我在上面输出 $document 时,我得到了我正在处理的正确文档,这是我应该做的。但是,在更新功能中,如果我自己输出 $document 或者我这样做

public function update(Request $request, Project $project, Document $document)
{
    dd($project->document);

    return null;
}

我同时看到 DocumentA 和 DocumentB。更新不应该只通过 DocumentA 吗?

为什么会这样?非常感谢任何信息或建议。

非常感谢

【问题讨论】:

    标签: laravel-5 laravel-5.1


    【解决方案1】:

    我认为问题在于项目和文档之间的关系。您可能有文档 belongsTo 项目,并且项目有很多文档,因为您可以有许多 projectId = 1 的文档。不是吗? 我说的没问题,当你编写 $project->document 时,它会为你带来属于该项目的所有文档。这很令人困惑,因为您将关系命名为“文档”而不是“文档”。 你可以做两件事: 1- 如果每个项目只能有 1 个文档,请将“项目”模型中的关系更改为 hasOne Document。然后,如果你做 $project->document 它只会给你带来一个。 2- 如果您的应用程序允许一个项目有多个文档,请将关系保留为 hasMany(我建议将其重命名为文档而不是文档),并将 $document 对象传递给更新表单,而不是传递 $project并尝试从那里访问文档。 如果我错过了你的问题的重点,请告诉我,我完全错了

    【讨论】:

    • 您好,感谢您的意见。一个项目可以有很多文档,所以我应该将它重命名为文档。目前,我的编辑视图有正确的文档。如果我通过表单传递这个文档对象,当我在控制器中输出文档时,它似乎是一个空对象。你知道为什么会这样吗?
    • 我可以看看你的更新方法的路线吗?我在将动态参数传递给 laravel 中的 post/patch 路由时遇到了问题(个人经验),所以我会修改你的代码中的两件事。在表格中,写 {!! Form::model($document, [ 'etc' ]) !!} 而不是 $project->document/s (如果你重命名了关系)。移除补丁路由中的动态参数。如果您需要将项目传递给控制器​​,请将其 id 作为表单中的隐藏变量传递。您在表单中的路线现在应该是 'route' => 'projects.documents.update' 。在控制器中写入 dd($request->input());
    • 所以,很抱歉坚持。我希望你看到你表格中的错误。如果你需要更新项目的第二个文档,你会写什么? $project->document 也不起作用。这就是为什么你应该给它特定的 $document。 $project->document 返回一个集合,而不是 Document 实例
    • 嗨,我现在实际上已经找到了解决方案。该表单传递了我正在处理的文档的 ID,然后我使用它在我的控制器中获取正确的文档。似乎工作。谢谢
    猜你喜欢
    • 1970-01-01
    • 2018-02-15
    • 2019-01-20
    • 2015-11-24
    • 2022-01-24
    • 2021-02-06
    • 2018-09-23
    • 2018-10-06
    • 1970-01-01
    相关资源
    最近更新 更多