【问题标题】:Laravel: How to get Models out of query results?Laravel:如何从查询结果中获取模型?
【发布时间】:2019-08-20 21:24:39
【问题描述】:

假设我有一个查询,除其他外,它返回用户 ID,这个查询是使用 DB::table()... 而不是使用模型构建的,因此,我得到了一个包含每个检索行的数组的集合,一些像这样:

user_id | calculated_data
--------+----------------
      1 |     123
      2 |     111
      3 |     222
    ... |     ...

假设我将此集合存储在 $data 变量中,当然如果我这样做 foreach ($data as $d) { $d->user_id ... } 将起作用。

但我希望这个查询返回更像 ORM 所做的事情,所以 user_ids 会返回用户模型,以便我可以做,例如 $data->user->name

这甚至可以做到吗?如果有,怎么做?

【问题讨论】:

  • 准确地说是 5.8.32
  • @miken32 只是想知道,但我对这个问题的标记出了什么问题?
  • 特定于版本的标签最适合用于特定于版本的功能。因此,如果在 v 5 中引入了一个新功能并且您正在询问它,您将使用 laravel-5。这是从第一天开始就存在的框架的基本功能,因此与版本无关的标签就足够了。
  • 除其他外是没有人能真正帮助你的原因。我们不知道您是如何到达所提供的桌子的,以及那里还有什么其他东西。您将不得不求助于User::find(...); 或使用(正确的)加入请求对原始数据库语句进行 ORM 化。
  • 您应该在问题中包含示例查询和数据,而不是评论为什么它们不适合您的答案。人们想要帮助并需要所有信息才能这样做。

标签: php laravel eloquent


【解决方案1】:

您可以使用hydrate() 函数,它接受stdClass 对象(甚至关联数组AFAIR)的array 作为输入并返回Eloquent Modelscollection,因此您可以执行以下操作:

$result = DB::table('users')->take(10)->get();
$users = App\User::hydrate($result->all()); 

您甚至可以使用fromQuery() 函数直接从原始查询中获取Eloquent Models 的集合,即:

$users = App\User::fromQuery('SELECT * FROM users WHERE id > ?', [2])

更新:如果您的集合中没有hydrate 模型的所有字段,您可以使用一个查询预加载您需要的所有用户并修改您的collection,即:

$users = App\User::find($data->pluck('user_id'));
$data->transform(function($item) use($users) {
            $item->user = $users->where('id', $item->user_id)->first()
            return $item;
        }); 

【讨论】:

  • 看来,hydrate() 你必须传递一个完整的对象(我的意思是数据),可以说,将其转换为模型,在我的情况下,我没有镜像表示对象,因为它包含其他数据,但是谢谢,知道这一点很有趣!
  • @luisfer 您发布了一个通用问题,没有查询也没有数据转储,您得到了一个通用的答案,恕我直言,这是您提供的详细信息可以找到的最佳答案。跨度>
【解决方案2】:

您需要使用 Eloquent 以“ORM 方式”调用值我没有找到任何与 ORM 相关的查询构建器。

你可以这样做:

$flights = App\Flight::all(); 

foreach ($flights as $flight) {
    echo $flight->name;
}

而在 ORM 中,你会得到这样的用户:

foreach ($flights as $flight) {
    echo $flight->user->name;
}

当然,您需要设置正确的关系。

【讨论】:

  • 是的,我知道如何使用 ORM。但在这种情况下,我必须做的事情超出了我对 ORM 的了解,我有两个视图(不是表)来提供我需要的数据
【解决方案3】:
// initial query will return collection of objects
$query = DB::table('user_something')
   ->join('users', 'users.id', 'user_something.user_id');

// You could cast it to the model query, by using fromSub.
// Make sure to alias a subquery same as the model's name,
// otherwise it would not be able to parse models data
User::fromSub($query, 'users');

// The most robust way is to get table name from the model
User::fromSub($query, User::make()->getTable());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多