检索多态关系 laravel 的所有者

Posted

技术标签:

【中文标题】检索多态关系 laravel 的所有者【英文标题】:Retrieve the owner of a polymorphic relationship laravel 【发布时间】:2019-11-14 11:41:21 【问题描述】:

我正在尝试检索我在我的应用程序中定义的 Eloquent 多态关系的所有者。这是关系:Theme 可以由 EnseignantPartenaire 发布,因此两者都可以发布主题。下面是对应的模型和多态关系:

Theme型号

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Theme extends Model


    public function themePoster()
        return $this->morphTo();
    


Enseignant型号

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Enseignant extends Model



    public function utilisateur()
        return $this->belongsTo('App\Utilisateur');
    

    public function themes()
        return $this->morphMany('App\Theme', 'themePoster');
    

Partenaire型号

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Partenaire extends Model



    public function utilisateur()
        return $this->belongsTo('App\Utilisateur');
    

    public function themes()
        return $this->morphMany('App\Theme', 'themePoster');
    


我正在尝试在我的刀片视图中检索theme 的所有者,如doc 中所示。

这是控制器show函数:

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    
        $theme = Theme::findOrFail($id);
        return view('themeShow', ['theme' => $theme]);
    

themeShow 刀片视图

@extends('layouts.layout')

@section('content')
<body>
$theme->intitule <br>
$theme->categorie <br>
$theme->filiereDesiree <br>
$theme->description <br>
<a href=" url('themes') "><button>Voir tous</button></a>
@if(Auth::guard('web')->user()->hasRole('etudiant'))
<a href=""><button>Choisir thématique</button></a>
Proposé par  $theme->themePoster 
@elseif(Auth::guard('web')->user()->id == $theme->themePoster_id)
<a href="  url('themes/' .$theme->id. '/edit' )  "><button>Modifier thématique</button></a>
<form method="POST" action="  route('themes.destroy', $theme->id )  ">
    @csrf
    @method('DELETE')
<a class="btn btn-danger"> <input  class="delete" type="submit" name="submit" value="Supprimer thématique"><i class="fa fa-trash"></i></a>
</form>
@endif
@jquery
<script type="text/javascript">
    $("input[type=submit]").on("click", function()
        return confirm('Etes-vous sûr de vouloir de supprimer cette thématique?');
    );
</script>
</body>
@endsection

所以这是应该检索主题所有者的行:

Proposé par  $theme->themePoster 

但我什么也没得到:Proposé par:什么都没有返回。我在那里想念什么..?我是 Laravel 的新手,因为这是我的第一个应用程序,也是第一次使用多态关系。非常欢迎您的帮助

编辑

因为这些信息可能有助于理解。这是我的数据库结构:

Utilisateurs

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUtilisateursTable extends Migration

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    
        Schema::create('utilisateurs', function (Blueprint $table) 
            $table->bigIncrements('id');
            $table->string('nom');
            $table->string('prenom');
            $table->string('username')->unique();
            $table->string('email')->unique();
            $table->string('password');
            $table->string('fonction');
            $table->rememberToken();
            $table->timestamps();
        );
    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        Schema::dropIfExists('utilisateurs');
    


注意:EnseignantPartenaire 继承 Utilisateur

Utilisateur的型号

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Utilisateur extends Authenticatable

    use Notifiable;

    protected $table = 'utilisateurs';

    public function hasRole($role)
        return $this->fonction == $role;
    

    public function etudiants()
        return $this->hasMany('App\Etudiant');
    

    public function enseignants()
        return $this->hasMany('App\Enseignant');
    

    public function partenaires()
        return $this->hasMany('App\Partenaire');
    


Enseignants

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateEnseignantsTable extends Migration

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    
        Schema::create('enseignants', function (Blueprint $table) 
            $table->bigIncrements('id');
            $table->integer('utilisateur_id')->unique();
            $table->string('isAdmin');
            $table->string('nomEntreprise')->nullable();
            $table->string('descEntreprise')->nullable();
            $table->timestamps();
        );
    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        Schema::dropIfExists('enseignants');
    


Partenaires

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePartenairesTable extends Migration

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    
        Schema::create('partenaires', function (Blueprint $table) 
            $table->bigIncrements('id');
            $table->integer('utilisateur_id')->unique();
            $table->string('structure');
            $table->string('description_structure');
            $table->timestamps();
        );
    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        Schema::dropIfExists('partenaires');
    


基本上,themePoster_idthemePoster_type 是通过获取当前的 EnseignantPartenaire id 和函数来创建的。下面是负责获取这些属性的代码:

<input type="hidden" id="themePoster_id" name="themePoster_id" value= "Auth::guard('web')->user()->id">
<input type="hidden" id="themePoster_type" name="themePoster_type" value= "Auth::guard('web')->user()->fonction">

正如您在theme table 的示例中看到的,它已被很好地记录,但我遇到了这个 $theme-&gt;themePoster 的问题,它在这里没有返回任何内容。

【问题讨论】:

欢迎来到 Laravel!首先,您能多谈谈您的数据库结构吗?其次,确认$theme-&gt;themePoster_id$theme-&gt;themePoster_type 是否有值。第三, $theme-&gt;themePoster 将输出一个对象,通常不应该作为字符串输出。 谢谢!:)。我已经编辑了这个问题,以便您可以更清楚地了解我想要做什么。对于 $theme-&gt;themePoster ,我尝试了documentation 中所说的那样,就像我认为他们在其中使用的相同逻辑.. 或者我通常应该怎么做才能检索它..? 一个突出的事情是使用user()-&gt;iduser()-&gt;fonction 作为你的变形类。这不是错误的,但在您上面声明“主题可以由EnseignantPartenaire 发布”而不是User。另一件事,我认为这就是它找不到任何东西的原因,是使用了错误的themePoster_idthemePoster_class。如果没有人已经这样做了,我将在今天晚些时候发布答案。 对于user()-&gt;iduser()-&gt;fonction 部分,我使用中间件确保可以访问themeCreate 视图的登录用户是EnseignantPartenaire 和它工作正常。谢谢你的评论 【参考方案1】:

正如docs 中所述,我们(默认情况下)需要以下内容:

正确的数据库列。 正确的关系声明。

在您的情况下,这将是以下内容:

// Themes table:
$table->morphs('themePoster');

// Which is short for:
$table->string('themePoster_type');
$table->unsignedBigInteger('themePoster_id');


// Partenaire and Enseignant models:
public function themes()

    return $this->morphMany('App\Theme', 'themePoster');


// Theme model:
public function themePoster()
    return $this->morphTo();

(Source) 的 morphs

可以通过这种方式关联多态模型:

$partenaire->themes()->create([
    ...
]);

// The default behavior will result in this theme db record:
 themePoster_type | themePoster_id | more columns here 
 -----------------|----------------|-------------------
 'App\Partenaire' | 1              | ...

我认为您的代码出错的部分是themePoster_type 的值。假设您的记录将如下所示:

themePoster_type | themePoster_id | more columns here 
 -----------------|----------------|-------------------
 'partenaire'     | 1              | ...

Laravel 找不到 partenaire 作为模型,所以它不知道应该在哪个表中查找。我的假设是 Laravel 会抛出异常,但我可能错了。

简而言之,我认为带有Auth::guard('web')-&gt;user()-&gt;fonctioninput 发送的值不正确。在您的情况下,它应该是 App\PartenaireApp\Enseignant

Laravel provides 一种将某些字符串映射到正确类的解决方案。如果我说的问题是正确的,这将是一个很好的解决方案。您可以将键映射到正确的类。这将导致:

// AppServiceProvider@boot
Relation::morphMap([
    'partenaire' => 'App\Partenaire',
    'enseignant' => 'App\Enseignant',
]);

【讨论】:

感谢您非常详细的回答。我变得更好了,为什么它似乎不起作用。我刚刚尝试了您的解决方案,仍然遇到同样的问题,没有任何返回 我知道这肯定与我如何注册 themePoster_typethemePoster_id 值有关.. 但是我在这里如何注册它们,我的意思是这样 Laravel 会知道它们是 @ 987654337@ 或 App\Partenaire 实例属性。正如我上面所说.. 我只得到当前登录的用户 idfonction 并且可以访问该视图的用户是 EnseignantPartenaire 它会根据该类型获取相应的属性值用户的

以上是关于检索多态关系 laravel 的所有者的主要内容,如果未能解决你的问题,请参考以下文章

如何最好地链接到 Laravel 中的多态关系

如何在 Laravel 中对所有行使用多态关系?

Laravel - 反向多态关系

从 Laravel 中的关系中检索关系

如何在多对多关系 Laravel 中检索所有相关模型?

我需要知道用于查询嵌套关系并返回结果的 Laravel Eloquent 语法