Return 来自 Laravel / Laravel Nova 中另一个模型的数据

Return data from another model in Laravel / Laravel Nova

我的问题:

In Laravel Nova, how can I display the Country Name based on the Country ID?

我有 2 个 table:

  1. 国家
  2. countries_price

  1. 国家table拥有id, name等等
  2. countries_price table 持有 id, country_id, country_price

型号: (Laravel & Nova)

在国家/地区模型中 (Laravel):

    public function countryPrice() {
        return $this->hasOne('App\CountryPrice');
    }

在国家/地区价格模型中 (Laravel):

    public function countries()
    {
        return $this->hasMany('App\Country', 'id', 'country_id');
    }

国家模式(Nova):

HasOne::make('CountryPrice'),

在国家/地区价格模型 (Nova) 中:

HasMany::make('Countries'),

我在尝试什么:

在国家/地区价格模型中 (Laravel)

    public function getCountryName() {
        return Country::where('id', $this->country_id)->first()->name;
    }

国家/地区价格模型 (Nova)

    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            ID::make('Country ID','country_id'),

// TRYING TO PULL IN COUNTRY NAME HERE
            Text::make('Country Name', function () {
                $countryName= $this->getCountryName;
                return $countryName;
            }),

            Text::make('Base Price', 'trip_cost'),
            HasMany::make('Countries'),
        ];
    }


我的错误:

App\CountryPrice::getCountryName Must return a relationship instance


我不明白这个错误,需要帮助才能正常工作。任何帮助将不胜感激。

根据您的评论进行更新

您似乎在 Country 和 CountryPrice 之间建立了一对一的关系。可以这样读:"A Country has one CountryPrice and each CountryPrice belongs to one and only one Country".

可以通过以下方式建立该关系: 国家模式

public function countryPrice()
{
    return $this->hasOne(CountryPrice::class);
}

国家/地区价格模型

public function country()
{
    return $this->belongsTo(Country::class);
}

然后相应地更新新星实体: 国家资源

public function fields(Request $request)
{
    return [
        // ...
        HasOne::make('Country Prices'),
        // ...
    ];
}

国家/地区价格资源

public function fields(Request $request)
{
    return [
        // ...
        BelongsTo::make('Country'),
        // ...
    ];
}

然后在 Country nova 资源中指定标题 属性,正如我在下面的旧回答中所解释的那样:

/**
 * The single value that should be used to represent the resource when being displayed.
 *
 * @var string
 */
public static $title = 'name';

当您从 nova 界面创建 CountryPrice 记录时,生成的系统将允许您从 select 框中选择一个国家/地区。在 Country nova 索引中,您还将看到每个国家及其分配的价格。

我希望这是您需要的正确行为。如果这不正确,请告诉我,我会在 Stack Overflow 上打开一个聊天室,以便我们可以准确地找出您需要的内容并解决问题。


下面是旧答案

修复关系

我认为你的人际关系设置错误。从您发布的 table 架构看来,每个 Country 可以有很多 CountryPrice 因为您将 country_id 列放在 country_prices.

因此,如果"Country has many Country Prices",则"Each CountryPrice belongs to a single Country"。

If I misinterpreted your relationship, let me know in the comments the correct one and I'll fix my answer.

你可以这样设置这两个关系:

国家模式

public function countryPrices()
{
    return $this->hasMany(CountryPrice::class);
}

国家/地区价格模型

public function country()
{
    return $this->belongsTo(Country::class);
}

然后更新两个 Nova 资源以匹配新关系:

国家资源

public function fields(Request $request)
{
    return [
        // ...
        HasMany::make('Country Prices'),
        // ...
    ];
}

国家/地区价格资源

public function fields(Request $request)
{
    return [
        // ...
        BelongsTo::make('Country'),
        // ...
    ];
}

解释当前异常

App\CountryPrice::getCountryName Must return a relationship instance

您遇到的错误与 Nova 本身无关。发生这种情况是因为模型中定义的每个(非静态)方法都应该是查询范围、模型 accessor/mutator 或关系。

这意味着如果您定义 getCountryName 它将被视为一个关系并且需要 return 一个关系实例,但是您 return 是一个字符串。

在您的用例中,您实际上不需要定义访问器。您可以使用:

$countryPrice->country->name

CountryPrice 个实例上。


修复显示标题

要修复 CountryPrice 资源上 BelongsTo select 输入中显示的 Country 选择,您必须定义 title 属性 或将在您链接到的 Nova 资源 class 中完全用于此目的的方法(在您的示例中为 Country)。

您可以使用:

/**
 * The single value that should be used to represent the resource when being displayed.
 *
 * @var string
 */
public static $title = 'name';

或者,如果您需要从其他 attributes/transformations 计算标题 属性:

/**
 * Get the value that should be displayed to represent the resource.
 *
 * @return string
 */
public function title()
{
    // You can make advanced transformations/processing of any value here
    // $this will refer to the current resource instance.
    return $this->name;
}

这也适用于全局搜索。


参考资料

Laravel一对多关系:https://laravel.com/docs/6.x/eloquent-relationships#one-to-many

Laravel 访问器:https://laravel.com/docs/6.x/eloquent-mutators#defining-an-accessor

Nova 资源 Title/Subtitle 属性:https://nova.laravel.com/docs/2.0/search/global-search.html#title-subtitle-attributes