是否可以在不创建新属性的情况下过滤检索到的关系上的数据?

时间:2019-02-11 19:49:50

标签: php laravel

我在one to manyusers之间有posts关系。

我想知道我是否渴望在帖子中加载内容,可以在没有在User模型上创建新属性的情况下修改收藏集。

$user = User::with('posts')->get();

// Filter the posts on the user using business logic.
// Below is an example. I DO NOT want to do this logic in the db/query builder.

// Arbitrary business rule that is not easily possible to calculate in DB
$shouldGetTestPost = true;

$user->posts = $user->posts->filter(function($post) use ($shouldGetTestPost) {
    if ($shouldGetTestPost && $post->name = 'test') {
        return true;
    }

    return false;
});

dd($user);

如果我运行上述代码,laravel将创建一个名为posts的新属性,并将该集合分配给该属性,而不用修改关系。

例如

// I've removed irrelevant model data
App\User {#1145
  #table: "users"
  #attributes: array:6 [
    "id" => 1
    "email" => "test@test.com"
    "password" => "secret"
    "updated_at" => "2019-02-11 18:56:35"
    "created_at" => "2019-02-11 18:56:35"
    // Below is new
    "posts" => Illuminate\Database\Eloquent\Collection {#1217
      #items: array:1 [
        0 => App\Post {#1269
          #table: "posts"
          #attributes: array:24 [
            "id" => 1
            "name" => 'test'
            "user_id" => 1
          ]
        }
      ]
    }
  ]
  #original: array:5 [...]
  #relations: array:1 [
    "posts" => Illuminate\Database\Eloquent\Collection {#1264
      #items: array:2 [
        0 => App\Post {#1269}
        1 => App\Post {#1234
          #table: "posts"
          #attributes: array:24 [
            "id" => 1
            "name" => 'test'
            "user_id" => 1
          ]
        }
      ]
    }
  ]
]

发生的另一件有趣的事情是,在#relations中,数据已从items数组中删除,但引用仍然保留。参见0 => App\Post {#1269}

这是给laravel用的吗?我知道laravel优先考虑关系的属性,但是它不会改变关系数组似乎很奇怪。

我如何只更改关系集合而不创建新属性?

1 个答案:

答案 0 :(得分:1)

setRelation方法可用于覆盖关系中存储的内容。

$model->setRelation($relation, $value) 

https://laravel.com/api/5.7/Illuminate/Database/Eloquent/Concerns/HasRelationships.html#method_setRelation

但是,在极少数情况下这很有用,因此我仍然认为这是XY问题。您可以通过将闭包作为第二个参数传递到with()来进行constrain the eager loading查询,这将是有条件地检索相关项目的解决方案。