代码之家  ›  专栏  ›  技术社区  ›  Tom Headifen

您是否可以在不创建新属性的情况下筛选已检索关系的数据?

  •  0
  • Tom Headifen  · 技术社区  · 6 年前

    我有 one to many 之间的关系 users 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将创建一个名为 帖子 并将集合分配给该属性,而不是修改关系。

    例如

    // 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将属性优先于关系,但它不会改变关系数组,这似乎很奇怪。

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Devon Bessemer    6 年前

    setRelation方法可用于重写存储在关系中的内容。

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

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

    然而,在很少的情况下,这是有用的,所以我仍然相信这是一个xy问题。你可以 constrain the eager loading 通过将闭包作为第二个参数传递给 with() 这将是有条件地检索相关项的解决方案。