MVC (Laravel) donde agregar lógica

137

Digamos que cada vez que hago una operación CRUD o modifico una relación de una manera específica, también quiero hacer otra cosa. Por ejemplo, cada vez que alguien publica una publicación, también quiero guardar algo en una tabla para análisis. Quizás no sea el mejor ejemplo, pero en general hay mucha de esta funcionalidad "agrupada".

Normalmente veo este tipo de lógica en los controladores. Eso está muy bien hasta que quieras reproducir esta funcionalidad en muchos lugares. Cuando comienzas a entrar en parciales, crear una API y generar contenido ficticio, se convierte en un problema para mantener las cosas SECAS.

Las formas en que he visto administrar esto son eventos, repositorios, bibliotecas y agregar a modelos. Aquí están mis entendimientos de cada uno:

Servicios: aquí es donde la mayoría de las personas probablemente pondrían este código. Mi principal problema con los servicios es que a veces es difícil encontrar una funcionalidad específica en ellos y siento que se olvidan cuando las personas se centran en usar Eloquent. ¿Cómo sabría que necesito llamar a un método publishPost()en una biblioteca cuando puedo hacerlo $post->is_published = 1?

La única condición en la que veo que esto funciona bien es si SOLO usa los servicios (e idealmente hace que Eloquent sea inaccesible de alguna manera desde todos los controladores).

En última instancia, parece que esto solo crearía un montón de archivos innecesarios adicionales si sus solicitudes generalmente siguen la estructura de su modelo.

Repositorios: por lo que entiendo, esto es básicamente como un servicio, pero hay una interfaz para que pueda cambiar entre ORM, que no necesito.

Eventos: veo esto como el sistema más elegante en cierto sentido porque sabe que los eventos de su modelo siempre se llamarán con métodos Eloquent, por lo que puede escribir sus controladores como lo haría normalmente. Sin embargo, puedo ver que estos se vuelven desordenados y si alguien tiene ejemplos de proyectos grandes que usan eventos para el acoplamiento crítico, me gustaría verlo.

Modelos: Tradicionalmente, tenía clases que realizaban CRUD y también manejaban el acoplamiento crítico. Esto realmente facilitó las cosas porque sabía que todas las funcionalidades relacionadas con CRUD +, lo que sea que tuviera que hacer con él, estaban allí.

Simple, pero en la arquitectura MVC esto normalmente no es lo que veo hecho. En cierto sentido, prefiero esto a los servicios, ya que es un poco más fácil de encontrar y hay menos archivos de los que hacer un seguimiento. Sin embargo, puede ser un poco desorganizado. Me gustaría escuchar las desventajas de este método y por qué la mayoría de las personas no parecen hacerlo.

¿Cuáles son las ventajas / desventajas de cada método? ¿Me estoy perdiendo de algo?

Sabrina Leggett
fuente
3
¿Puedes minimizar tu pregunta?
The Alpha
3
También puedes comprobar esto .
The Alpha
1
"¿Cómo sabría que necesito llamar a un método publishingPost () en una biblioteca cuando puedo hacer $ post-> is_published = 1?" ¿Documentación?
ceejayoz
Una de las bellezas sobre elocuente y ORMS es que es más fácil trabajar con ellos sin muchos documentos.
Sabrina Leggett
1
Gracias por publicar esto. Estoy luchando con los mismos problemas y encontré tu publicación y respuesta increíblemente útil. Finalmente, he decidido que Laravel no proporciona una buena arquitectura para nada que se extienda más allá de un sitio web rápido y sucio de Ruby-on-Rails. Tratas por todas partes, dificultad para encontrar funciones de clases y toneladas de basura mágica automática en todas partes. ORM nunca ha funcionado y si lo está usando, probablemente debería estar usando NoSQL.
Alex Barker

Respuestas:

171

Creo que todos los patrones / arquitecturas que presenta son muy útiles siempre que siga los principios de SOLID .

Para saber dónde agregar lógica , creo que es importante hacer referencia al Principio de responsabilidad única . Además, mi respuesta considera que estás trabajando en un proyecto mediano / grande. Si es un proyecto de tirar algo en una página , olvide esta respuesta y agréguela a los controladores o modelos.

La respuesta corta es: dónde tiene sentido para usted (con servicios) .

La respuesta larga:

Controladores : ¿Cuál es la responsabilidad de los Controladores? Claro, puede poner toda su lógica en un controlador, pero ¿es esa la responsabilidad del controlador? No lo creo.

Para mí, el controlador debe recibir una solicitud y devolver datos y este no es el lugar para poner validaciones, llamar a métodos db, etc.

Modelos : ¿Es este un buen lugar para agregar lógica como enviar un correo electrónico de bienvenida cuando un usuario se registra o actualiza el recuento de votos de una publicación? ¿Qué sucede si necesita enviar el mismo correo electrónico desde otro lugar en su código? ¿Creas un método estático? ¿Qué pasa si ese correo electrónico necesita información de otro modelo?

Creo que el modelo debería representar una entidad. Con laravel, sólo utilizar la clase modelo para agregar cosas como fillable, guarded, tabley las relaciones (esto es porque uso el patrón de repositorio, de lo contrario el modelo también tendría los save, update, findmétodos, etc).

Repositorios (patrón de repositorio) : Al principio estaba muy confundido por esto. Y, como usted, pensé "bueno, uso MySQL y eso es todo".

Sin embargo, he equilibrado los pros y los contras de usar el Patrón de repositorio y ahora lo uso. Creo que ahora , en este mismo momento, solo necesitaré usar MySQL. Pero, si dentro de tres años necesito cambiar a algo como MongoDB, la mayor parte del trabajo está hecho. Todo a expensas de una interfaz adicional y a $app->bind(«interface», «repository»).

Eventos ( patrón de observador ): los eventos son útiles para cosas que se pueden lanzar en cualquier clase en cualquier momento dado. Piense, por ejemplo, en enviar notificaciones a un usuario. Cuando lo necesita, activa el evento para enviar una notificación a cualquier clase de su aplicación. Luego, puede tener una clase como UserNotificationEventsesa que maneje todos sus eventos activados para las notificaciones de los usuarios.

Servicios : hasta ahora, tiene la opción de agregar lógica a los controladores o modelos. Para mí, tiene sentido agregar la lógica dentro de los Servicios . Seamos realistas, Servicios es un nombre elegante para las clases. Y puede tener tantas clases como tenga sentido dentro de su aplicación.

Tome este ejemplo: Hace poco desarrollé algo así como los Formularios de Google. Empecé con una CustomFormServicey terminó con CustomFormService, CustomFormRender, CustomFieldService, CustomFieldRender, CustomAnswerServicey CustomAnswerRender. ¿Por qué? Porque tenía sentido para mí. Si trabaja con un equipo, debe poner su lógica donde tenga sentido para el equipo.

La ventaja de usar Servicios vs Controladores / Modelos es que no está limitado por un solo Controlador o un solo Modelo. Puede crear tantos servicios como sea necesario según el diseño y las necesidades de su aplicación. Agregue a eso la ventaja de llamar a un Servicio dentro de cualquier clase de su aplicación.

Esto es largo, pero me gustaría mostrarle cómo he estructurado mi aplicación:

app/
    controllers/
    MyCompany/
        Composers/
        Exceptions/
        Models/
        Observers/
        Sanitizers/
        ServiceProviders/
        Services/
        Validators/
    views
    (...)

Yo uso cada carpeta para una función específica. Por ejemplo, el Validatorsdirectorio contiene una BaseValidatorclase responsable de procesar la validación, basada en $rulesy $messagesde validadores específicos (generalmente uno para cada modelo). Podría poner fácilmente este código dentro de un Servicio, pero tiene sentido para mí tener una carpeta específica para esto, incluso si solo se usa dentro del servicio (por ahora).

Le recomiendo que lea los siguientes artículos, ya que podrían explicarle las cosas un poco mejor:

Rompiendo el molde por Dayle Rees (autor de CodeBright): Aquí es donde lo armé todo, a pesar de que cambié algunas cosas para satisfacer mis necesidades.

Desacoplar su código en Laravel utilizando repositorios y servicios de Chris Goosey: esta publicación explica bien qué es un servicio y el patrón de repositorio y cómo encajan entre sí.

Los Laracasts también tienen los Repositorios de responsabilidad simple y simplificada, que son buenos recursos con ejemplos prácticos (aunque tenga que pagar).

Luís Cruz
fuente
3
Gran explicación. Aquí es donde estoy parado en este momento: en el proyecto actual estoy poniendo mi lógica de negocios en modelos y en realidad está funcionando muy bien. Definitivamente necesitamos un poco de SOLID, pero realmente no nos ha metido en problemas todavía. Es rápido, está un poco sucio, pero hasta ahora nuestro proyecto es muy fácil de mantener porque es muy SECO. Definitivamente estoy de acuerdo con seguir con ellos en este momento porque hacen el trabajo, pero en cualquier proyecto futuro probablemente seguiré con lo que sea estándar, que parece que se han convertido en repositorios.
Sabrina Leggett
2
Me alegra que hayas encontrado una manera que tenga sentido para ti. Solo tenga cuidado con las suposiciones que hace hoy . He trabajado en un proyecto durante más de 3 años y terminé con controladores y modelos con más de 5000 líneas de código. Buena suerte con tu proyecto.
Luís Cruz
También estaba un poco sucio, pero estaba pensando en usar rasgos para evitar que los modelos se volvieran enormes. De esa manera puedo separarlos un poco
Sabrina Leggett
Este artículo se articula bien CUANDO tiene sentido usar los servicios. En su ejemplo de Formulario, tiene sentido usar servicios, pero amplía cómo lo hace, que es cuando la lógica está directamente relacionada con un modelo que lo coloca en ese modelo. justinweiss.com/articles/where-do-you-put-your-code
Sabrina Leggett
Me gusta mucho la explicación. Hay una pregunta que tengo: mencionó que no debe poner validación en el controlador, entonces, ¿dónde cree que es el mejor lugar para hacer la validación? Muchos sugieren ponerlo en la clase Solicitud extendida (y también en lo que hacemos actualmente), pero ¿qué pasa si no solo quiero validar en la solicitud http, sino también en el comando artesanal, etc., es realmente un buen lugar?
kingshark
24

Quería publicar una respuesta a mi propia pregunta. Podría hablar sobre esto durante días, pero voy a tratar de publicar esto rápidamente para asegurarme de que lo levante.

Terminé utilizando la estructura existente que proporciona Laravel, lo que significa que mantuve mis archivos principalmente como Modelo, Vista y Controlador. También tengo una carpeta de Bibliotecas para componentes reutilizables que no son realmente modelos.

NO ENVOLVÉ MIS MODELOS EN SERVICIOS / BIBLIOTECAS . Todas las razones proporcionadas no me convencieron al 100% del beneficio de usar los servicios. Si bien puedo estar equivocado, por lo que puedo ver, solo resultan en toneladas de archivos adicionales casi vacíos que necesito crear y cambiar cuando trabajo con modelos y también reducen realmente el beneficio de usar elocuencia (especialmente cuando se trata de RECUPERAR modelos , p. ej., utilizando paginación, ámbitos, etc.).

Puse la lógica comercial EN LOS MODELOS y accedo directamente desde mis controladores elocuentes. Utilizo una serie de enfoques para asegurarme de que no se omita la lógica empresarial:

  • Accesores y mutadores: Laravel tiene excelentes accesores y mutadores. Si deseo realizar una acción cada vez que una publicación se mueve de borrador a publicado, puedo llamar a esto creando la función setIsPublishedAttribute e incluyendo la lógica allí
  • Anulación de Crear / Actualizar, etc.: siempre puede anular los métodos Eloquent en sus modelos para incluir una funcionalidad personalizada. De esa manera, puede llamar a la funcionalidad en cualquier operación CRUD. Editar: creo que hay un error al anular la creación en versiones más recientes de Laravel (por lo que uso eventos ahora registrados en el arranque)
  • Validación: conecto mi validación de la misma manera, por ejemplo, ejecutaré la validación anulando las funciones CRUD y también los accesores / mutadores si es necesario. Vea Esensi o dwightwatson / validating para más información.
  • Métodos Mágicos: uso los métodos __get y __set de mis modelos para conectarlos a la funcionalidad cuando sea apropiado
  • Elocuente extendido: si hay una acción que le gustaría realizar en todas las actualizaciones / crear, incluso puede extender elocuente y aplicarlo a múltiples modelos.
  • Eventos: Este es un lugar directo y generalmente acordado para hacer esto también. El mayor inconveniente con los eventos, creo, es que las excepciones son difíciles de rastrear (podría no ser el nuevo caso con el nuevo sistema de eventos de Laravel). También me gusta agrupar mis eventos por lo que hacen en lugar de cuando se los llama ... por ejemplo, tener un suscriptor de MailSender que escucha los eventos que envían correo.
  • Agregar eventos Pivot / BelongsToMany: Una de las cosas con las que luché por más tiempo fue cómo asociar el comportamiento a la modificación de las relaciones belongToMany. Por ejemplo, realizar una acción cada vez que un usuario se une a un grupo. Ya casi termino de pulir una biblioteca personalizada para esto. ¡Todavía no lo he publicado pero es funcional! Intentaremos publicar un enlace pronto. EDITAR Terminé convirtiendo todos mis pivotes en modelos normales y mi vida ha sido mucho más fácil ...

Abordar las preocupaciones de las personas con el uso de modelos:

  • Organización: Sí, si incluye más lógica en los modelos, pueden ser más largos, pero en general he descubierto que el 75% de mis modelos siguen siendo bastante pequeños. Si elijo organizar los más grandes, puedo hacerlo usando rasgos (por ejemplo, crear una carpeta para el modelo con algunos archivos más como PostScopes, PostAccessors, PostValidation, etc., según sea necesario). Sé que esto no es necesariamente para qué sirven los rasgos, pero este sistema funciona sin problemas.

Nota adicional: Siento que envolver sus modelos en servicios es como tener una navaja suiza, con muchas herramientas, y construir otra navaja alrededor que básicamente haga lo mismo. Sí, a veces es posible que desee cortar con cinta una cuchilla o asegurarse de que dos cuchillas se usen juntas ... pero generalmente hay otras formas de hacerlo ...

CUANDO UTILIZA LOS SERVICIOS : Este artículo articula muy bien GRANDES ejemplos de cuándo usar los servicios ( pista: no es muy frecuente ). Básicamente, dice que cuando su objeto usa múltiples modelos o modelos en partes extrañas de su ciclo de vida , tiene sentido. http://www.justinweiss.com/articles/where-do-you-put-your-code/

Sabrina Leggett
fuente
2
Pensamientos interesantes y válidos. Pero tengo curiosidad: ¿cómo prueba unitariamente su lógica empresarial si está vinculada a modelos que están vinculados a Eloquent, que está vinculado a la base de datos?
JustAMartin
code.tutsplus.com/tutorials/… o puede usar eventos como dije si desea desglosarlos aún más
Sabrina Leggett
1
@JustAMartin ¿está seguro de que no puede usar la base de datos en sus pruebas unitarias? ¿Cuál es la razón para no hacerlo? Muchas personas están de acuerdo en que a menudo está bien usar la base de datos en pruebas unitarias. (incluido Martin Fowler, martinfowler.com/bliki/UnitTest.html : "No trato el uso de dobles para recursos externos como una regla absoluta. Si hablar con el recurso es estable y lo suficientemente rápido para usted, entonces no hay razón para no hacerlo en las pruebas de tu unidad ")
Alex P.
@ AlexP11223 Sí, eso tiene sentido. Traté de integrar SQLite como mi base de datos de prueba y, en general, funcionó bien, aunque SQLite tiene algunas limitaciones serias que deben tenerse en cuenta en las migraciones de Laravel y las consultas personalizadas (si las hay). Por supuesto, esas no son estrictamente pruebas unitarias sino pruebas funcionales, pero es aún más eficiente de esa manera. Aún así, si desea probar su modelo en completo aislamiento (como una prueba unitaria estricta), puede requerir una cantidad notable de código adicional (simulacros, etc.).
JustAMartin
22

Lo que suelo hacer para crear la lógica entre controladores y modelos es crear una capa de servicio . Básicamente, este es mi flujo para cualquier acción dentro de mi aplicación:

  1. El controlador obtiene la acción solicitada por el usuario y los parámetros enviados y delega todo a una clase de servicio.
  2. La clase de servicio realiza toda la lógica relacionada con la operación: validación de entrada, registro de eventos, operaciones de base de datos, etc.
  3. El modelo contiene información de campos, transformación de datos y definiciones de validaciones de atributos.

Así es como lo hago:

Este es el método de un controlador para crear algo:

public function processCreateCongregation()
{
    // Get input data.
    $congregation                 = new Congregation;
    $congregation->name           = Input::get('name');
    $congregation->address        = Input::get('address');
    $congregation->pm_day_of_week = Input::get('pm_day_of_week');
    $pmHours                      = Input::get('pm_datetime_hours');
    $pmMinutes                    = Input::get('pm_datetime_minutes');
    $congregation->pm_datetime    = Carbon::createFromTime($pmHours, $pmMinutes, 0);

    // Delegates actual operation to service.
    try
    {
        CongregationService::createCongregation($congregation);
        $this->success(trans('messages.congregationCreated'));
        return Redirect::route('congregations.list');
    }
    catch (ValidationException $e)
    {
        // Catch validation errors thrown by service operation.
        return Redirect::route('congregations.create')
            ->withInput(Input::all())
            ->withErrors($e->getValidator());
    }
    catch (Exception $e)
    {
        // Catch any unexpected exception.
        return $this->unexpected($e);
    }
}

Esta es la clase de servicio que realiza la lógica relacionada con la operación:

public static function createCongregation(Congregation $congregation)
{
    // Log the operation.
    Log::info('Create congregation.', compact('congregation'));

    // Validate data.
    $validator = $congregation->getValidator();

    if ($validator->fails())
    {
        throw new ValidationException($validator);
    }

    // Save to the database.
    $congregation->created_by = Auth::user()->id;
    $congregation->updated_by = Auth::user()->id;

    $congregation->save();
}

Y este es mi modelo:

class Congregation extends Eloquent
{
    protected $table = 'congregations';

    public function getValidator()
    {
        $data = array(
            'name' => $this->name,
            'address' => $this->address,
            'pm_day_of_week' => $this->pm_day_of_week,
            'pm_datetime' => $this->pm_datetime,
        );

        $rules = array(
            'name' => ['required', 'unique:congregations'],
            'address' => ['required'],
            'pm_day_of_week' => ['required', 'integer', 'between:0,6'],
            'pm_datetime' => ['required', 'regex:/([01]?[0-9]|2[0-3]):[0-5]?[0-9]:[0-5][0-9]/'],
        );

        return Validator::make($data, $rules);
    }

    public function getDates()
    {
        return array_merge_recursive(parent::getDates(), array(
            'pm_datetime',
            'cbs_datetime',
        ));
    }
}

Para obtener más información sobre esta forma, utilizo para organizar mi código para una aplicación Laravel: https://github.com/rmariuzzo/Pitimi

Rubens Mariuzzo
fuente
Parece que los servicios son lo que denominé bibliotecas en mi publicación. Creo que esto es mejor que los repositorios si no necesita usar múltiples ORMS, pero el problema es que tiene que migrar todo su proyecto (que no tiene que ver con los eventos), y parece que simplemente termina reflejando la estructura del Modelo, por lo que acaba de obtener todos estos archivos adicionales. ¿Por qué no solo incluirlo en los modelos? Al menos de esa manera no tienes los archivos adicionales.
Sabrina Leggett
Esa es una pregunta interesante @SabrinaGelbart, me han enseñado a dejar que los modelos representen las entidades de la base de datos y a no tener ninguna lógica. Esa es la razón por la que creé esos archivos adicionales nombrados como servicios: para mantener toda la lógica y cualquier operación adicional. No estoy seguro de cuál es el significado completo de los eventos que describió anteriormente, pero creo que con los servicios y el uso de los eventos de Laravel podemos hacer que todos los métodos de servicios disparen eventos al inicio y al final. De esta manera, cualquier evento puede ser completamente desacoplado de la lógica. ¿Qué piensas?
Rubens Mariuzzo
Me enseñaron que también sobre los modelos ... ¿sería bueno obtener una buena explicación de por qué (tal vez problemas de dependencia)?
Sabrina Leggett
Me gusta este enfoque! He estado buscando en Internet para tener una idea de cómo debería manejar la lógica del modelo, revisé los repositorios, pero parecía demasiado complicado e inútil para un poco de uso. Los servicios son una buena idea. Mi pregunta es después de crear una carpeta de Servicios en la carpeta de la aplicación, ¿tiene que incluirla en bootstrap / start.php o en cualquier lugar para arrancar porque miré por encima de su git no podía encontrarlo? @RubensMariuzzo. ¿Se vuelve disponible automáticamente a través de la aplicación? entonces podemos usar CongregationService :: getCongregations (); ??
Oguzhan
1
Si todo lo que está haciendo es un, $congregation->save();entonces tal vez no necesitaría repositorios. Sin embargo, es posible que vea que sus necesidades de acceso a datos aumentan con el tiempo. Puede comenzar a tener necesidades para $congregation->destroyByUser()o $congregationUsers->findByName($arrayOfSelectedFields);etc. ¿Por qué no desvincular sus servicios de las necesidades de acceso a datos? Deje que el resto de su aplicación trabaje con objetos / matrices devueltos por repositorios, y solo maneje la manipulación / formateo / etc ... Sus repositorios crecerán (pero los dividirá en diferentes archivos, en última instancia, la complejidad de un proyecto debe residir en algún lugar).
prograhammer
12

En mi opinión, Laravel ya tiene muchas opciones para que almacene su lógica de negocios.

Respuesta corta:

  • Use los Requestobjetos de laravel para validar automáticamente su entrada y luego persista los datos en la solicitud (cree el modelo). Como todas las entradas de los usuarios están directamente disponibles en la solicitud, creo que tiene sentido realizar esto aquí.
  • Use los Jobobjetos de laravel para realizar tareas que requieren componentes individuales, luego simplemente envíelos. Creo que Jobabarcan clases de servicio. Realizan una tarea, como la lógica empresarial.

Respuesta larga (er):

Use repositorios cuando sea necesario: los repositorios están obligados a sobrebloquearse, y la mayoría de las veces, simplemente se usan como un accessormodelo. Siento que definitivamente tienen algún uso, pero a menos que esté desarrollando una aplicación masiva que requiera esa cantidad de flexibilidad para poder deshacerse por completo de laravel, manténgase alejado de los repositorios. Te lo agradecerás más tarde y tu código será mucho más sencillo.

Pregúntese si existe la posibilidad de que vaya a cambiar los marcos PHP o a un tipo de base de datos que no sea compatible con laravel.

Si su respuesta es "Probablemente no", no implemente el patrón de repositorio.

Además de lo anterior, no coloque un patrón encima de un ORM excelente como Eloquent. Solo está agregando complejidad que no es necesaria y no lo beneficiará en absoluto.

Utilice los servicios con moderación: las clases de servicios para mí son solo un lugar para almacenar la lógica empresarial para realizar una tarea específica con sus dependencias dadas. Laravel los tiene listos para usar, llamados 'Empleos', y tienen mucha más flexibilidad que una clase de Servicio personalizada.

Siento que Laravel tiene una solución completa para el MVCproblema lógico. Es solo una cuestión u organización.

Ejemplo:

Solicitud :

namespace App\Http\Requests;

use App\Post;
use App\Jobs\PostNotifier;
use App\Events\PostWasCreated;
use App\Http\Requests\Request;

class PostRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title'       => 'required',
            'description' => 'required'
        ];
    }

    /**
     * Save the post.
     *
     * @param Post $post
     *
     * @return bool
     */
    public function persist(Post $post)
    {
        if (!$post->exists) {
            // If the post doesn't exist, we'll assign the
            // post as created by the current user.
            $post->user_id = auth()->id();
        }

        $post->title = $this->title;
        $post->description = $this->description;

        // Perform other tasks, maybe fire an event, dispatch a job.

        if ($post->save()) {
            // Maybe we'll fire an event here that we can catch somewhere else that
            // needs to know when a post was created.
            event(new PostWasCreated($post));

            // Maybe we'll notify some users of the new post as well.
            dispatch(new PostNotifier($post));

            return true;
        }

        return false;
    }
}

Controlador :

namespace App\Http\Controllers;

use App\Post;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{

   /**
    * Creates a new post.
    *
    * @return string
    */
    public function store(PostRequest $request)
    {
        if ($request->persist(new Post())) {
            flash()->success('Successfully created new post!');
        } else {
            flash()->error('There was an issue creating a post. Please try again.');
        }

        return redirect()->back();
    }

   /**
    * Updates a post.
    *
    * @return string
    */
    public function update(PostRequest $request, $id)
    {
        $post = Post::findOrFail($id);

        if ($request->persist($post)) {
            flash()->success('Successfully updated post!');
        } else {
            flash()->error('There was an issue updating this post. Please try again.');
        }

        return redirect()->back();
    }
}

En el ejemplo anterior, la entrada de la solicitud se valida automáticamente, y todo lo que necesitamos hacer es llamar al método de persistencia y pasar una nueva publicación. Creo que la legibilidad y la facilidad de mantenimiento siempre deben superar los patrones de diseño complejos e innecesarios.

Luego puede utilizar exactamente el mismo método de persistencia para actualizar las publicaciones, ya que podemos verificar si la publicación ya existe o no y realizar una lógica alternativa cuando sea necesario.

Steve Bauman
fuente
pero, ¿no se "supone" que los trabajos estén en cola? A veces, probablemente queremos que esté en cola, pero no todo el tiempo. ¿Por qué no usar comandos en su lugar? ¿Qué sucede si desea escribir alguna lógica empresarial que pueda ejecutarse como un comando o un evento o en cola?
Sabrina Leggett
1
Los trabajos no necesitan estar en cola. Usted especifica eso implementando la interfaz en el trabajo ShouldQueueque proporciona Laravel. Si desea escribir lógica empresarial en un comando o evento, simplemente active el trabajo dentro de esos eventos / comandos. Los trabajos de Laravels son extremadamente flexibles, pero al final son simples clases de servicio.
Steve Bauman