php - Ardent+Laravel, relación auto hidrato
eloquent (1)
Yo uso lavarel con un paquete ardiente.
Tengo un problema cuando quiero actualizar una fila.
Tengo 2 clientes modelo y dirección relacionados por la relación morphone.
Esta relación funciona bien, cuando quiero obtener un cliente, esta línea devuelve el resultado esperado:
Client::with(''address'')->find($id);
Pero no puedo entender cómo actualizar un cliente con una solución limpia. Alguien puede responder a estas preguntas:
- Con Ardent, ¿cómo puedes autoHydrate el modelo relacionado?
- Cuando actualiza algunos datos, ¿cuál es la mejor práctica en lavarel? Use update methdod? Use guardar? Usa push? Llenar todo modelo? ¿Usar hidrato automático?
Cuando registro Input :: all () en mi método de actualización, obtengo eso:
[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":"[email protected]","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"}} [] []
Como puede ver, los datos de la dirección están dentro de los datos del cliente.
3. Cuando uso update, save o push (método elocuente) elocuente no entiende que debe actualizar el modelo de dirección y luego actualizar el modelo de cliente relacionado. El formato de mis datos no está bien formado?
Gracias.
ACTUALIZAR:
Cuando hago Log :: info (Input :: all ()), obtengo los siguientes datos json en mi controlador:
[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":"[email protected]","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"}} [] []
Con la autohidratación de ardent que no funciona ... El cliente se autohidrata con éxito pero Address no lo hace, tal vez debido a la relación polimórfica (uno a uno) entre ellos.
Intento llenar mis modelos de esta manera:
$client = Client::with(''address'')->find($id);
$client->update(Input::except(''address''));
$client->address->update(Input::only(''address''));
pero esto no funciona porque Input :: only (''address'') da datos formados incorrectamente, cuando registro esto obtengo eso:
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":"[email protected]"} [] []
[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"}} [] []
Así que mezclo dos métodos:
$inputs = Input::except(''_method'');
$client = Client::with(''address'')->find($id);
$client->update(Input::except(''address''));
$client->address->update($inputs[''address'']);
¡Este funciona bastante bien!
Pero no puedo entender por qué la autohidratación ardiente falla ...
Gracias.
No hay nada tan clean
o best practice
pero la situación lo demanda. Puede intentar algo como esto dependiendo de su necesidad:
// 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();
Una cosa que debe saber es que, en ambos models
( Client
y Address
), debe proporcionar una matriz protected $fillable = [''propeertyName'']
o una matriz vacía para manejar la asignación masiva . En este caso, si tiene un campo de name
en la tabla de clients
y en la tabla de addresses
si tiene un campo de block
, entonces puede usar;
$client->fill(array(''name'' => ''Jhon''))
->address->fill(array(''block'' => ''d''))
->push();
En este caso, ambos campos se actualizarán en ambas tablas. Si envía todos los campos usando un formulario que contiene propiedades para el Client
y la Address
entonces debe elegir los campos de formulario / elementos apropiados de la matriz de entrada. Así por ejemplo:
$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();
También puedes usar:
$client = Client::with(''address'')->find($id);
$client->fill(Input::all()); // Or maybe Input::only([...]) or except([...])
$client->address->city = ''someNewCity'';
$client->push();
Puede usar save
en ambos modelos de forma individual, pero push
guardará por usted. También puedes probar
$client = Client::with(''address'')->find($id);
$client->update(Input::except(''city''));
$client->address->update(Input::only(''city''));
De hecho, save
o push
podría aplicarse si los modelos están llenos con sus campos / propiedades y create/update
llenan los modelos primero usando el método de fill
y luego guardarlos, eso es todo.
Por cierto, no estoy seguro acerca de Ardent
.