【问题标题】:Laravel 5.1 and Fractal: including pivot table data on the transformerLaravel 5.1 和 Fractal:包括转换器上的数据透视表数据
【发布时间】:2015-12-18 06:33:54
【问题描述】:

表:contact、company 和带有自定义透视属性的关系表 company_contact (company_id, contact_id, is_main)

Company 和 Contact 具有多对多关系(belongsTo 在两种模型上)。

检索公司联系人时的预期输出:

{
    "data": [
        {
            "id": 1,
            "name": "JohnDoe",
            "is_main": false
        },
        {
            "id": 2,
            "name": "JaneDoe",
            "is_main": true
        }
    ]
}

当我使用?include=companies 检索联系人列表时的预期输出:

{
    "data": [
        {
            "id": 1,
            "name": "John Doe",
            "companies": {
                "data": [
                    {
                        "id": 501,
                        "name": "My Company",
                        "is_main": true
                    },
                    {
                        "id": 745,
                        "name": "Another Company",
                        "is_main": false
                    }
                ]
            }
        },
        {
            "id": 2,
            "name": "Jane Doe",
            "companies": {
                "data": [
                    {
                        "id": 999,
                        "name": "Some Company",
                        "is_main": true
                    }
                ]
            }
        }
    ]
}

添加数据透视表属性的最佳方法是什么?如果设置了属性,在公司转换器上添加is_main似乎不是很干净。

对于第一个示例,我正在考虑使用参数?include=company_relationship:company_id(1),例如:

public function includeCompanyRelationship(Contact $contact, ParamBag $params) {
    // .. retrieve the pivot table data here
    $is_main = $company->is_main;

    // but now I would need another transformer, when what I actually want is to push the value on the main array (same level)

    return $this->item(??, ??);
}

我了解如何检索数据透视数据(相关:Laravel 5.1 - pivot table between three tables, better option?),但不是在https://github.com/thephpleague/fractal Transformer 逻辑中添加它的最佳方式。

我已经有一个 ContactTransformer 和 CompanyTransformer,但是如果我将 is_main 添加到 CompanyTransformer 我所做的所有呼叫(与联系人相关或不与联系人相关)也将期望该属性。

【问题讨论】:

    标签: php api laravel-5.1 thephpleague thephpleague-fractal


    【解决方案1】:

    如果我没看错,您可以使用单个CompanyTransformer 来处理您是否希望设置is_main 属性,但前提是$contact 参数被传递给它的构造函数,其他的这些行:

    class CompanyTransformer extends TransformerAbstract
    {
        public function __construct(Contact $contact = null)
        {
            $this->contact = $contact;
        }
    
        public function transform(Company $company)
        {
            $output = [
                'id' => $company->id,
                'name' => $company->name,
            ];
    
            if($this->contact) {
                // This step may not be necessary, but I don't think the pivot data 
                // will be available on the $company object passed in
                $company = $this->contacts->find($company->id);
                // You may have to cast this to boolean if that is important
                $output['is_main'] = $company->pivot->is_main;
            }
    
            return $output;
        }
    }
    

    然后在您的includeCompanyRelationship 中,只需传入带有参数的新CompanyTransformer:

    public function includeCompanyRelationship(Contact $contact) 
    {
        $companies = $contact->companies;
    
        return $this->collection($companies, new CompanyTransformer($contact));
    }
    

    无论您是直接调用 companies 端点,还是在嵌入公司关系数据时调用联系人的端点,这都应该有效。

    【讨论】:

    • 我最终在构造函数上创建了一个参数数组,因为我有很多复杂的关系(不幸的是丢失了类型提示)。看起来很难看,但它的工作原理!而且我不传递实体,而是传递 ID,因为我可能需要,例如,多对多关系中单个项目的枢轴值。
    【解决方案2】:

    我知道这是较旧的,但我刚刚遇到了这个问题。以下是我的解决方法。

    将withPivot 添加到关系中,在我的情况下为category 和users。

    在 CategoryTransformer 中,我定义了我的 includeUsers 方法:

    /**
     * Include Users
     * @param Category $category
     * @return \League\Fractal\Resource\Collection
     */
     public function includeUsers(Category $category)
     {
         # Just Add withPivot Here.
         $users = $category->users()->withPivot('role')->get();
         return $this->collection($users, new UserTransformer);
     }
    

    然后在您的UserTransformer 类中,在transform() 方法上:

    public function transform($user)
    {
        return [
            'username' => $user['username'],
            'lastname' => $user['lastname'],
            // ... truncated
            'role' => isset($user['pivot']) ? $user['pivot']['role'] : null,
        ]
    }
    

    然后,当我为categories 调用我的api 并包含users 时,我得到:

    {
      "data": [
        {
          "name": "Network",
          "description": "some description of category here.",
          "users": {
            "data": [
              {
                "id": 1,
                "username": "jborne",
                "firstname": "Jason",
                "lastname": "Borne",
                "title": "Department Head",
                "company": "Borne Inc",
                "email": "jason@somedomain.com",
                "display_name": "Jason Borne",
                "mobile": "555-5555",
                "active": true,
                "role": "IM",
              }
            ]
          }
        }
      ]
    }
    

    如您所见,我从枢轴获得了我想要的role 关系。否则,您只会为该字段获得null。仍然不理想,但在我看来不那么混乱了。

    【讨论】:

      猜你喜欢
      • 2016-08-04
      • 1970-01-01
      • 2016-02-12
      • 2015-10-04
      • 2021-10-20
      • 2018-04-10
      • 2015-09-30
      • 2021-08-17
      • 2019-09-17
      相关资源
      最近更新 更多