在 Eloquent 属性中返回查询的模型

Posted

技术标签:

【中文标题】在 Eloquent 属性中返回查询的模型【英文标题】:Return queried model in Eloquent attribute 【发布时间】:2017-04-18 23:01:21 【问题描述】:

我正在使用 Laravel 雄辩的 ORM,我希望能够将查询的 laravel 模型作为属性返回,或者更理想的是作为雄辩的关系返回。这就是我想要做的:

class CalendarEvent extends Model

    protected $appends = array('conflicts');

    public function getConflictsAttribute () 
        $conflicts =  CalendarEvent::where('calendar_event_type','=',$this->calendar_event_type)
                      ->where('start','<',$this->end)
                      ->where('end','>',$this->start)
                      ->get();   

        return $conflicts;
    

这是一种尝试获取重叠日历事件,这将是冲突事件,作为针对每个事件的对象返回。

这意味着任何查询运行都会返回冲突:

$event = CalendarEvent::where('id','=',123)->first()->toJson();
$event; // JSON object should contain conflicting events

这会导致非 laravel 500 错误和空白页面。 storage/logs/laravel 没有附加到。我的 /var/log/site-error.log 在请求期间附加了这个:

php 消息:PHP 324。 Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP 消息:PHP 325。 Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP 消息:PHP 326. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP 消息:PHP 327.array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 328。 Illuminate\Support\Collection->Illuminate\Supportclosure() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 329. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP 消息:PHP 330。 Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP 消息:PHP 331。 Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP 消息:PHP 332. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP 消息:PHP 333.array_map() /home/vagrant/silverback/ 2016/12/04 14:21:16 [错误] 792#0: *42880 FastCGI 在标准错误中发送: “home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 370。 Illuminate\Support\Collection->Illuminate\Supportclosure() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 371. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP 消息:PHP 372。 Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP 消息:PHP 373。 Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP 消息:PHP 374. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP 消息:PHP 375.array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 376。 Illuminate\Support\Collection->Illuminate\Supportclosure() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 377. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP 消息:PHP 378。 Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP 消息:PHP 379。 Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP 消息:PHP 380. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/larav 2016/12/04 14:21:16 [错误] 792#0: *42880 FastCGI 在标准错误中发送: “ck/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP 消息:PHP 417.array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 418。 Illuminate\Support\Collection->Illuminate\Supportclosure() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 419. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP 消息:PHP 420。 Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP 消息:PHP 421。 Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP 消息:PHP 422. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP 消息:PHP 423.array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 424。 Illuminate\Support\Collection->Illuminate\Supportclosure() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 425. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP 消息:PHP 426。 Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP 消息:PHP 427。 Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Mode 2016/12/04 14:21:16 [错误] 792#0: *42880 FastCGI 在标准错误中发送: “e/Database/Eloquent/Model.php:2518 PHP 消息:PHP 464。 Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP 消息:PHP 465.array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 466。 Illuminate\Support\Collection->Illuminate\Supportclosure() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 467. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP 消息:PHP 468。 Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP 消息:PHP 469。 Illuminate\Database\Eloquent\Model->mutateAttributeForArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2518 PHP 消息:PHP 470. Illuminate\Support\Collection->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2764 PHP 消息:PHP 471.array_map() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 472。 Illuminate\Support\Collection->Illuminate\Supportclosure() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1103 PHP 消息:PHP 473. Illuminate\Database\Eloquent\Model->toArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1102 PHP 消息:PHP 474。 Illuminate\Database\Eloquent\Model->attributesToArray() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2454 PHP 消息:PHP 475. Illuminate\Database\Eloquent\Model->mu 2016/12/04 14:21:16 [错误] 792#0: *42880 FastCGI 在标准错误中发送: “ry\Grammars\mysqlGrammar->wrapValue() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Grammar.php:79 PHP 消息:PHP 511。 Illuminate\Database\Query\Grammars\MySqlGrammar->isJsonSelector() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php:225 PHP 消息:PHP 512. Illuminate\Support\Str::contains() /home/vagrant/silverback/httpdocs/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php:255" 从上游读取响应头时,客户端:192.168.42.1, 服务器:silverback.dev,请求:“GET /test HTTP/1.1”,上游: “fastcgi://unix:/var/run/php5-fpm.sock:”,主机:“silverback.dev”

更新: 我已经决定使用 Eloquent ORM 是不可能的。我实际上想做的是像这样的 Mysql,作为关系附加:

select * from calendar_events as calendar_events_2 where calendar_events_2.start < calendar_events_1.end AND calendar_events_2.end > calendar_events_1.start

相反,我不情愿地选择了一个 foreach 循环来在获取数据后附加数据。我相信这是我唯一的选择。

foreach ($shoot_timeline_data as $shoot) 
    foreach ($shoot->booking_cases as $booking_case) 
        $booking_case->booking->conflicts = CalendarEvent::find_***es(
            $booking_case->booking->calendar_event_type, 
            $booking_case->booking->start, 
            $booking_case->booking->end,
            [$booking_case->booking->id] // excludes this ID via 'whereNotIn'
        );
    

【问题讨论】:

你能发布错误信息吗?您的代码似乎很好。这可能是由于格式更改或导致Carbon 错误和第二个或第三个where 子句产生错误的原因造成的字符丢失。在可以读取确切的错误消息之前,没有什么是清楚的。 我添加了更多关于错误的信息,并更改了我的代码示例以显示我试图通过预加载实现的目标。 【参考方案1】:

错误似乎是由附加属性引起的,您试图在数组中获取其他模型实例。另一种方法可能是在 self 上定义一个关系,例如

class CalendarEvent extends Model
    public function conflicts()
     
        return  $this->hasMany(CalendarEvent::class)
                ->where('calender_event_type','=', $this->calendar_event_type);
    
  

那么你可以尝试查询为

$event = CalendarEvent::where('id','=',123)->with('conflicts')->first()->toJson();  

尚未测试,但尝试看看它是否有效。

编辑

尝试使用带有延迟加载的参数

$event = CalendarEvent::where('id', '=', 123)->first();
or
$event = CalendarEvent::findOrFail(123);  //it will find the record by given primary key - 123 or fail i.e. throw 'MODELNOTFOUNDEXCEPTION'

$start = $event->start;
$end = $event->end;
$event->load('conflicts', function($query) use ($start, $end)
          $query->where('start', '<', $start)
                ->where('end', '>', $end)
        )->get();

【讨论】:

这似乎是前进的方向,我必须将其作为“惰性急切加载”运行,否则模型的 $this->start 为空。然而,即使是延迟加载,有时 $this->start 和 $this->end 也会返回为 null。这些数据库字段都不是空的。 $shoot_timeline_data->load([ 'booking_cases.booking.conflicts', ]); 在这种情况下,您可以在获取模型后加载关系。 $event=CalendarEvent::where ('id','=',123)-&gt;first(); 然后 `$event->load ('conflicts'); 这对我来说是有道理的,但是当我这样做是一种雄辩的关系时,例如: return $this->hasMany('App\CalendarEvent','calendar_event_type','calendar_event_type') ->where( 'start','end) ->where('end','>',$this->start) ; ,我收到错误:非法运算符和值组合:在 Builder->where('start', ' 但是,数据库值不为空。【参考方案2】:

你需要退货

class CalendarEvent extends Model

    protected $appends = array('conflicts');

    public function getConflictsAttribute () 
    
        return CalendarEvent::where('calendar_event_type','=',$this->calendar_event_type)
                      ->where('start','<',$this->end)
                      ->where('end','>',$this->start)
                      ->get();   
    

【讨论】:

对不起,我的真实代码要复杂得多,我已经简化了它,在我的问题中遗漏了那一行。我刚试过这个,我得到一个代码 500 错误,但不是 laravel 类型的。 "not of a laravel kind" 意味着日志中什么也没有显示? storage/logs/laravel.log

以上是关于在 Eloquent 属性中返回查询的模型的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Eloquent 查询关系中使用模型的属性

在哪里放置与 Eloquent 无关的 SQL 查询

相关模型 eloquent laravel 中的自定义查询

限制从 Laravel Eloquent 中连接的表/模型返回的字段

Laravel Eloquent ORM 无法正确返回模型的关系

Laravel 通过属性获得雄辩的查询构建器关系