【问题标题】:Ardent + Laravel, auto hydrate relationArdent + Laravel,自动水合物关系
【发布时间】:2014-07-21 05:48:15
【问题描述】:

我将 lavarel 与 ardent 包一起使用。

我想更新一行时遇到了一些问题。

我有 2 个模型 Client 和 Address 相关的 morphone 关系。

这种关系运作良好,当我想获得客户时,此行返回预期结果:

Client::with('address')->find($id);

但我不明白如何使用干净的解决方案更新客户端。有人可以回答这些问题:

  1. 有了 Ardent,你怎么能 autoHydrate 相关模型?
  2. 更新一些数据时,lavarel 的最佳实践是什么?使用更新方法?使用保存?使用推?填充所有模型?使用自动补水?

当我在更新方法中记录 Input::all() 时,我明白了:

[2014-05-31 15:52:56] production.INFO: {"id":983,"firstName":"Susanne","lastName":"Adam","birthDate":"18\/06\/1982","inscriptionDate":"08\/09\/2013","status":3,"created_at":"2014-05-31 14:26:25","updated_at":"2014-05-31 14:26:25","email":"bernard.alix@free.fr","address":{"id":983,"address":"avenue Etienne","address2":"","ville":"Cordierboeuf","cp":"25 10","phone":"0403983157","mobile":"+33 (0)3 0","addressable_id":983,"addressable_type":"Client","created_at":"2014-05-31 14:27:58","updated_at":"2014-05-31 14:27:58"}} [] []

如您所见,地址数据在客户数据中。

3.当我使用更新、保存或推送(eloquent 的方法)时,eloquent 不明白他应该更新 Address 模型然后更新相关的 Client 模型。我的数据格式不正确?

谢谢。

更新:

当我执行 Log::info(Input::all()) 时,我在控制器中得到以下 json 数据:

[2014-06-01 18:10:46] production.INFO: {"id":284,"firstName":"Andr\u00e9e","lastName":"Adam","birthDate":"23\/07\/1944","inscriptionDate":"22\/11\/2013","status":2,"created_at":"2014-06-01 15:41:22","updated_at":"2014-06-01 18:06:44","email":"monique17@normand.com","address":{"id":284,"streetAddress":"93, avenue Lefort","streetAddress2":"","city":"Boulay-sur-Leger","zipCode":"14054","phone":"09 51 03 1","mobile":"+33 6 00 6","addressable_id":284,"addressable_type":"Client","created_at":"2014-06-01 15:42:50","updated_at":"2014-06-01 18:06:44"}} [] []

由于 ardent 的自动水合不起作用...客户端自动水合成功但 Address 没有,可能是由于它们之间的多态关系(一对一)。

我尝试以这种方式填充我的模型:

$client = Client::with('address')->find($id);
$client->update(Input::except('address'));
$client->address->update(Input::only('address'));

但这不起作用,因为 Input::only('address') 给出了错误的格式数据,当我记录这个时,我明白了:

Log::info(Input::except('address'));
Log::info(Input::only('address'));

//output 

[2014-06-01 18:20:34] production.INFO: {"id":284,"firstName":"Andr\u00e9e","lastName":"Adam","birthDate":"23\/07\/1944","inscriptionDate":"22\/11\/2013","status":2,"created_at":"2014-06-01 15:41:22","updated_at":"2014-06-01 18:10:46","email":"monique17@normand.com"} [] []
[2014-06-01 18:20:34] production.INFO: {"address":{"id":284,"streetAddress":"93, avenue Lefort","streetAddress2":"","city":"Boulay-sur-Leger","zipCode":"14054","phone":"09 51 03 1","mobile":"+33 6 00 6","addressable_id":284,"addressable_type":"Client","created_at":"2014-06-01 15:42:50","updated_at":"2014-06-01 18:06:44"}} [] []

所以我混合了两种方法:

$inputs = Input::except('_method');
$client = Client::with('address')->find($id);

$client->update(Input::except('address'));
$client->address->update($inputs['address']);

这个效果很好!

但我不明白为什么 ardent 的自动补水失败...

谢谢。

【问题讨论】:

    标签: php laravel eloquent ardent


    【解决方案1】:

    没有什么像cleanbest practice 那样,而是情况需要。您可以根据需要尝试以下方法:

    // Get the Client
    $client = Client::with('address')->find($id);
    
    // Fill and save both Client and it's related model Address
    $client->fill(array(...))->address->fill(array(...))->push();
    

    您应该知道的一点是,在此处的modelsClientAddress)中,您需要提供一个protected $fillable = ['propeertyName'] 数组或一个空数组来处理mass assignment。在这种情况下,如果您在clients 表中有一个name 字段,并且在您的addresses 表中有一个block 字段,那么您可以只使用;

    $client->fill(array('name' => 'Jhon'))
           ->address->fill(array('block' => 'd'))
           ->push();
    

    在这种情况下,两个表中的两个字段都将更新。如果您使用包含ClientAddress 属性的表单提交所有字段,那么您必须从输入数组中选择适当的项目/表单字段。比如:

    $inputs = Input::except('_method'); // All fields for both tables in $inputs
    // Get the fields for Client model, get all
    // but not fields that belongs to address table
    $addressData = array('road', 'block', 'city');
    $clientData = Input::except($addressArray); // get all but fields of Address
    
    // Fill and save both Client and it's related model Address
    $client->fill($clientData)->address->fill($addressdata)->push();
    

    你也可以使用:

    $client = Client::with('address')->find($id);
    $client->fill(Input::all()); // Or maybe Input::only([...]) or except([...])
    $client->address->city = 'someNewCity';
    $client->push();
    

    您可以在两个模型中单独使用save,但push 会为您保存两者。你也可以试试

    $client = Client::with('address')->find($id);
    $client->update(Input::except('city'));
    $client->address->update(Input::only('city'));
    

    实际上,savepush 可以应用,如果模型填充了它们的字段/属性,create/update 首先使用 fill 方法填充模型然后保存它们,就是这样。

    顺便说一句,不确定Ardent

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-09
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      • 2019-12-15
      • 1970-01-01
      • 2015-02-13
      相关资源
      最近更新 更多