Ardent + Laravel, auto hydrate relation

早过忘川 提交于 2019-12-23 04:08:37

问题


I use lavarel with ardent package.

I have some problem when i want to update a row.

I have 2 model Client and Address related by morphone relation.

This relation work well, when i want to get a client this line return expected result :

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

But i can't understand how to update a client with a clean solution. Somebody can answer to these questions :

  1. With Ardent how could you autoHydrate related model ?
  2. When you update some data, what is the best practice in lavarel ? Use update methdod ? Use save ? Use push ? Fill all model ? Use auto hydrate ?

When i log Input::all() in my update method i get that :

[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"}} [] []

As you see address data are inside client data.

3.When I use update, save or push (eloquent's method) eloquent does not understand that he should update Address model then update related Client model. My data's format isn't well formed ?

Thanks.

UPDATE :

When i do Log::info(Input::all()), i get the following json data in my controller :

[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"}} [] []

With ardent's autohydratation that doesn't work... Client autohydrate successfully but Address does not, maybe due to the polymorphic relation (one-to-one) between them.

I try to fill my models this way :

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

but this doesn't work because Input::only('address') gives wrong formed data, when i log this i get that :

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"}} [] []

So i mix two methods :

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

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

This work pretty well !

But i can't understand why ardent's autohydration fails...

Thanks.


回答1:


There is nothing as clean or best practice but the situation demand. You may try something like these depending on your need:

// 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();

One thing you should know that, in both models here (Client and Address) you need to provide a protected $fillable = ['propeertyName'] array or an empty array to handle mass assignment. In this case if you have a name field in clients table and in your addresses table if you have a block field then you may just use;

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

In this case both fields will be updated in both tables. if you submit all the fields using a form that contains properties for both Client and Address then you have to pick the appropriate items/form fields from the input array. So for example:

$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();

Also you may use:

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

You may use save in both models individually but push saves both for you. Also you may try

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

Actually, save or push could be applied if the models are populated with their fields/properties and create/update fill the models first using fill method and then save them, that's it.

BTW, not sure about Ardent.



来源:https://stackoverflow.com/questions/23972017/ardent-laravel-auto-hydrate-relation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!