两种模型,两个字段,如果存在则返回首选值

时间:2019-11-20 12:41:42

标签: laravel laravel-5

一直在努力以最优化的方式做到这一点...

我有两个模型:CatalogApplication

Catalog有一个名为name的字段。

Application有一个名为name的字段。

彼此有关系。

我正在努力寻找一种创建可以在Laravel应用程序中使用的函数的方法,该函数将向其传递application.id并根据以下逻辑返回一个$app->name值:< / p>

  • 如果存在$application->name,请将此值用作$app->name对象的$application
  • 否则,获取$catalog->name值并将其用作$app->name

请注意,我想创建一个组件@application(),我可以在其中简单地传递$application->id并在其中构建显示逻辑(主题/样式)。

由于我在很多地方都显示了此$app->name,所以我想使其尽可能轻巧,以避免不必要的查询。

我希望这有道理!可能有很多方法可以使用,我迷失了进行此操作的方法:(

2 个答案:

答案 0 :(得分:0)

我不确定要完全了解您的模型/数据库设计,但是您可以使用自定义助手来在整个应用程序中使用该功能。

为此,您可以在Helper.php文件夹或所需的任何位置中创建一个简单的PHP类app/Http/Helpers文件。像这样:

<?php

use App\Catalog;
use App\Application;

if (! function_exists('getAppName')) {
    function getAppName($id){
        // Do your logic here to return the name
        $catalog = Catalog::find($id);
        return $catalog->name;
    }
}
?>

然后在任何控制器或视图中,您只需执行 getAppName($application->id)

请不要忘记将您的助手文件添加到作曲家自动加载中。因此,在Laravel根文件夹的composer.json中,将帮助程序路径添加到自动加载数组中:

"files": [
    "app/Http/Helpers/helpers.php"
],

最后但并非最不重要的是,运行以下命令: composer dump-autoload

请注意,由于我不知道您的模型结构,因此函数逻辑仅用于示例目的。

答案 1 :(得分:0)

我认为,我关心数据库的成本。

使用三元表达式会很优雅。但是,如果应用程序名称为空,则需要花费两倍于数据库的IO成本。

$app_name = Application::find($id)->name;
$app_name = empty($app_name) ? Catalog::where('application_id', $id)->first()->name;

这将更加复杂,但是catalog_query仅在application.nameempty时执行,它在数据库中执行并且结果仅被提取一次;

并且数据库只能从一个表或两个表中找到名称。

类似这样的东西:

$catalog_query = Catalog::where('catalogs.application_id', $id)->select('catalogs.name')->groupBy('catalogs.name'); 
// if catalogs and applications relationship is 1:1, use ->limit(1) or remove groupBy('name') is better.

Application::where("applications.id", $id)
           ->selectRaw("IF(application.name IS NULL OR application.name = '', (" . $catalog_query->toSql() ."), applications.name ) AS app_name")
           ->mergeBindings($catalog_query->getQuery())
           ->first()
           ->app_name;

希望这会对您有所帮助。