CursosEmpresasBlogLiveConfPrecios

Autenticación y Gestión de Ofertas en Symfony

Clase 2 de 17 • Curso de Symfony Framework

Contenido del curso

Symfony Framework

  • 1
    Crea una bolsa de empleo con Symfony

    Crea una bolsa de empleo con Symfony

    01:00 min
  • 2
    Autenticación y Gestión de Ofertas en Symfony

    Autenticación y Gestión de Ofertas en Symfony

    Viendo ahora
  • 3
    Desarrollo de Bolsa de Empleo con Symfony en PHP

    Desarrollo de Bolsa de Empleo con Symfony en PHP

    02:42 min
  • 4
    Modelo de Datos para Bolsa de Empleo: Entidades y Relaciones

    Modelo de Datos para Bolsa de Empleo: Entidades y Relaciones

    02:17 min
  • 5
    Virtualización y configuración de entornos de desarrollo con Homestead

    Virtualización y configuración de entornos de desarrollo con Homestead

    04:07 min
  • 6
    Creación y Configuración de un Proyecto Symfony con Homestead

    Creación y Configuración de un Proyecto Symfony con Homestead

    02:44 min
  • 7
    Creación de Entidades y Migraciones en Symfony

    Creación de Entidades y Migraciones en Symfony

    04:04 min
  • 8
    Creación de Controladores y Rutas en Symfony

    Creación de Controladores y Rutas en Symfony

    04:14 min
  • 9
    Listado y Creación de Empresas en Symfony

    Listado y Creación de Empresas en Symfony

    03:44 min
  • 10
    Control de Acceso y Creación de Usuarios en Symfony

    Control de Acceso y Creación de Usuarios en Symfony

    06:12 min
  • 11
    Creación de usuarios en Symfony para administradores

    Creación de usuarios en Symfony para administradores

    02:41 min
  • 12
    Listado y Postulación a Ofertas de Trabajo en Symfony

    Listado y Postulación a Ofertas de Trabajo en Symfony

    07:08 min
  • 13
    Layouts y herencia de templates en Twig

    Layouts y herencia de templates en Twig

    03:06 min
  • 14
    Envío de Correos en Symfony con Mailer y Transport

    Envío de Correos en Symfony con Mailer y Transport

    02:01 min
  • 15
    Despliegue de Aplicaciones Symfony en Producción

    Despliegue de Aplicaciones Symfony en Producción

    05:16 min
  • 16
    Comparativa de Frameworks PHP: Symfony, Laravel y Más

    Comparativa de Frameworks PHP: Symfony, Laravel y Más

    02:08 min
  • 17
    Symfony proyecto terminado: certifica y planifica

    Symfony proyecto terminado: certifica y planifica

    00:38 min
Tomar examen

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads

      ¿Qué puede hacer la empresa?

      Lo primero que debe poder hacer una empresa es publicar ofertas.

      Claro que, para lograrlo, primero deberá identificarse, es decir, pasar por LoginFormAuthenticator::onAuthenticationSuccess.

      Para ver ese código abre el archivo src/Security/LoginFormAuthenticator.php.

      Lo primero que habrá que hacer será extender el if para incluir, por lo menos, un nuevo caso:

      $roles = $token->getUser()->getRoles(); if ( in_array( 'ROLE_ADMIN', $roles) ) { return new RedirectResponse($this->urlGenerator->generate('company')); } elseif ( in_array('ROLE_COMPANY', $roles) ) { ... }

      Una vez identificado que se trata de un usuario responsable de una empresa, resta saber de qué empresa se trata.

      Para ello haremos una consulta a través de Doctrine.

      Dado que se trata de una consulta simple podemos usar el método findOneBy de la clase CompanyRepository: vamos a buscar una empresa cuyo dueño sea el usuario que ha iniciado sesión:

      $company = $this->entityManager->getRepository(Company::class)->findOneBy([ 'owner' => $token->getUser(), ]) Aquí se ve cómo utilizamos el servicio entityManager (disponible porque ha sido inyectado en el constructor del controlador) para obtener acceso al repositorio correspondiente a la entidad Company.

      El criterio de búsqueda establece que el campo owner debe coincidir con el usuario obtenido del token.

      En caso de haberse obtenido tal compañía haremos una redirección hacia una página que nos muestre las ofertas publicadas por ella.

      El código completo se verá de esta forma:

      public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) { return new RedirectResponse($targetPath); } $roles = $token->getUser()->getRoles(); if ( in_array( 'ROLE_ADMIN', $roles) ) { return new RedirectResponse($this->urlGenerator->generate('company')); } elseif ( in_array('ROLE_COMPANY', $roles) ) { if ( $company = $this->entityManager->getRepository(Company::class)->findOneBy([ 'owner' => $token->getUser(), ])){ return new RedirectResponse($this->urlGenerator->generate('company_offers', [ 'id' => $company->getId() ])); } } // For example : return new RedirectResponse($this->urlGenerator->generate('some_route')); throw new \Exception('TODO: provide a valid redirect inside '.__FILE__); }

      Lo que vemos aquí es cómo generamos una URL usando el método generate del servicio urlGenerator.

      El primer parámetro es el nombre de la ruta que usaremos, el segundo es un arreglo de parámetros para la ruta.

      Es lo mismo que habíamos visto anteriormente cuando usamos la función url de Twig.

      Pero… un momento, ¿dónde está definida la ruta company_offers? ¡En ningún lado! Un poquito de paciencia por favor. :)

      Lo que precisamos justamente es un método en algún controlador que responda a una ruta llamada de ese modo. ¿Qué mejor momento que este para crearlo?

      Ya que se trata de una acción referida a una empresa, es una buena idea que el método forme parte del controlador CompanyController.

      Algo que sabemos es que tendrá que tener asociada una ruta llamada company_offers y que, en algún lado del patrón de URL deberá existir un argumento llamado id.

      Una posibilidad es definir la ruta de este modo:

      @Route("/company/{id}/offers", name="company_offers")

      Las {} son un placeholder que se transformará en un parámetro para el método que maneje esta ruta.

      Es decir, una url como /company/10/offers será atendida por este método y uno de sus parámetros se llamará $id (y su valor será 10).

      Con lo cual, la misión por delante será encontrar una empresa cuyo id coincida con el parámetro recibido y mostrar sus ofertas o dar un 404 en caso de que no exista.

      Consiguiendo las ofertas de la empresa

      Un modo de obtener la empresa sería definir el método de esta forma:

      public function showOffers(int $id)

      Y realizar la búsqueda mediante una llamada a algún find de Doctrine. Eso no estaría mal, pero sería más laborioso que lo necesario (además de dejar de nuestro lado el manejo de situaciones como el caso de no encontrar a la empresa).

      Symfony nos propone un método mejor.

      Podemos definir el método directamente así:

      /** * @Route("/company/{id}/offers", name="company_offers") */ public function showOffers(Company $company) { ... }

      Nuevamente, la magia de Symfony (bueno, en este caso debemos darle algo de crédito a Doctrine también).

      Para comenzar, el framework está comprendiendo que $company será un objeto de clase Company (Esta parte es fácil: ¡se lo estamos diciendo nosotros!).

      Luego, se está enterando de que se trata de una entidad manejada por Doctrine (ya que la clase Company está definida utilizando el annotation @ORM\Entity).

      Y luego, sabe que deberá realizar el find porque existe un atributo llamado id dentro de la definición de dicha entidad.

      Con lo cual, en caso de no encontrarlo se generará en forma automática un error 404, de modo que nosotros podemos asumir que si el método se ejecuta es porque la entidad en cuestión existe en la base de datos.

      Interesante, ¿no? :)

      Una vez obtenida, simplemente pasémosla al template para que se encargue de la visualización:

      return $this->render('company/show_offers.html.twig', [ 'company' => $company, ]);

      El template quedará de esta forma:

      {% extends 'base.html.twig' %} {% block title %}Ofertas publicadas{% endblock %} {% block body %} <style> .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } </style> <div class="example-wrapper"> <h1>Ofertas publicadas</h1> {% if company.offers | length %} <table> <thead> <tr> <th>Título</th> </tr> </thead> <tbody> {% for o in company.offers %} <tr> <td>{{ o.title }}</td> </tr> {% endfor %} </tbody> </table> {% else %} <p>Aún no se han publicado ofertas</p> {% endif %} </div> {% endblock %}

      Falta agregar el link para crear una nueva oferta y armar el formulario para crear la nueva oferta… imagino que sabrás cómo hacerlo, ¿cierto? :)

      Visualizando los candidatos a una publicación

      Nos resta ver cómo mostrar los candidatos a cada publicación.

      Comencemos por armar un método que muestre los detalles de una oferta.

      Dado que se trata de un método que actúa sobre una oferta es una buena idea hacerlo parte del OfferController:

      Lo primero que necesitamos es… pues crearlo :)

      Como siempre, usaremos el comando php bin/console make:controller Offer

      Y siendo que vamos a hacer un método que permita visualizar una oferta, llamémosle show:

      * @Route("/offer/{id}", name="offer_show") */ public function show(Offer $offer) { return $this->render('offer/show.html.twig', [ 'offer' => $offer, ]); }

      El template debería verse similar a:

      {% extends 'base.html.twig' %} {% block title %}Ofertas publicadas{% endblock %} {% block body %} <style> .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } </style> <div class="example-wrapper"> <h1>Oferta "{{ offer.title }}"</h1> {% for a in offer.applicants %} ... </div> {% endblock %}

      Pero si miramos la clase Offer vemos que no tiene ningún método getApplications ni tampoco una propiedad $applications…

      Niño pregutándose y ahora qué

      Es tiempo de refinar nuestro modelo (mejor dicho: es tiempo de completar la implementación de nuestro modelo).

      Para comenzar, aún no hemos creado la entidad Applicant.

      Aquí no hay mucho misterio, usa el comando php bin/console make:entity Applicant y listo.

      Ten en cuenta relacionar al Applicant con un User.

      Una propiedad interesante que tendrá esta entidad es applications. Es aquí donde implementaremos nuestra relación Muchos-A-Muchos con la clase Offer.

      Cuando el asistente te pregunte contesta Sí a crear un método Offer::getApplicants.

      Una vez finalizada, crea la migración usando php bin/console make:migration.

      Si miras el archivo de migración generado te encontrarás con que hay una tabla extra:

      CREATE TABLE applicant_offer (applicant_id INTEGER NOT NULL, offer_id INTEGER NOT NULL, PRIMARY KEY(applicant_id, offer_id))

      Pero en realidad no debería ser ninguna sorpresa: es así cómo se implementa una relación N-a-M.

      Perfecto, ahora ejecuta la migración y avancemos.

      Ya podemos escribir el template con confianza:

      {% extends 'base.html.twig' %} {% block title %}Ofertas publicadas{% endblock %} {% block body %} <style> .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } </style> <div class="example-wrapper"> <h1>Oferta "{{ offer.title }}"</h1> {% if offer.applicants | length %} <table> <thead> <tr> <td>Postulante</td> <td>Correo</td> </tr> </thead> <tbody> {% for a in offer.applicants %} <tr> <td>{{ a.name }}</td> <td><a href="mailto:{{ a.email }}">{{ a.email }}</a></td> </tr> {% endfor %} </tbody> </table> {% else %} <p>Aún no se han recibido postulaciones</p> {% endif %} </div> {% endblock %}

      Bien, con esto la empresa ya cuenta con la información necesaria para ver qué pasó con sus ofertas y contactar a los postulantes si lo desea.

      Lo único que resta es darle un link para poder ver esta información.

      Para ello, retoca el template templates/company/show_offers.html.twig de modo que se vea así:

      {% extends 'base.html.twig' %} {% block title %}Ofertas publicadas{% endblock %} {% block body %} <style> .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } </style> <div class="example-wrapper"> <h1>Ofertas publicadas</h1> {% if company.offers | length %} <table> <thead> <tr> <th>Título</th> <th>Postulantes</th> </tr> </thead> <tbody> {% for o in company.offers %} <tr> <td>{{ o.title }}</td> <td><a href="{{ url('offer_show', { id: o.id } ) }}">{{ o.applicants | length }}</a></td> </tr> {% endfor %} </tbody> </table> {% else %} <p>Aún no se han publicado ofertas</p> {% endif %} <a href="{{ path('new_offer', { id: company.id }) }}">Nueva oferta</a> </div> {% endblock %}

      ¡Perfecto! Ya va tomando forma, ¿no?

      Nuestra aplicación ya permite:

      • Crear nuevas empresas.
      • Crear nuevas ofertas.

      Falta la última pata: permitir a los candidatos postularse a las ofertas.

      Veámoslo en la próxima clase.

      Comentarios

      Carlos Eduardo Gomez García

      Carlos Eduardo Gomez García

      teacher•
      hace 5 años
        Jonathan Fernando Santana Quispillo

        Jonathan Fernando Santana Quispillo

        student•
        hace 4 años
      Cristian Orlando Rincon Bonilla

      Cristian Orlando Rincon Bonilla

      student•
      hace 6 años
        Javier Aliaga

        Javier Aliaga

        student•
        hace 5 años
      Additiu Digital

      Additiu Digital

      student•
      hace 5 años
      Walther Tristán

      Walther Tristán

      student•
      hace 4 años
        Magdiel Linares

        Magdiel Linares

        student•
        hace 4 años
      Jimmy Buriticá Londoño

      Jimmy Buriticá Londoño

      student•
      hace 5 años
      Moises Lazaro

      Moises Lazaro

      student•
      hace 4 años
      Kenet Andrés Chungandro Montenegro

      Kenet Andrés Chungandro Montenegro

      student•
      hace 6 años
      Germán Alejandro Niño

      Germán Alejandro Niño

      student•
      hace 5 años
      Kenet Andrés Chungandro Montenegro

      Kenet Andrés Chungandro Montenegro

      student•
      hace 6 años
      Oscar Velásquez

      Oscar Velásquez

      student•
      hace 4 años
      Sergio Ramirez

      Sergio Ramirez

      student•
      hace 4 años
      Jesús Emmanuel López Guerrero

      Jesús Emmanuel López Guerrero

      student•
      hace 4 años
      Diego Alejandro Toro Reyes

      Diego Alejandro Toro Reyes

      student•
      hace 5 años
      Gustavo Marín

      Gustavo Marín

      student•
      hace 5 años
      Mauricio Acevedo Rueda

      Mauricio Acevedo Rueda

      student•
      hace 6 años
      Nilson Reyes Sigua

      Nilson Reyes Sigua

      student•
      hace 5 años

      Nada, creo que continuaré el curso con solo lectura, demasiadas cosas sueltas, se le hace tan fácil decir: "Nada mas crea esto" pero en ningún momento explica cómo crearlo ni con qué campos ni que opciones elegir.

      Claro, el profesor porque ya sabe, nosotros estamos aprendiendo.

      Concuerdo. NO SE PUEDE APRENDER ASI. PAra me voy a la documentación no mas.

      Estoy súper perdido, me quedé en la parte donde hay que crear la entidad de aplicante, igual llevo varios cabos sueltos de clases anteriores, sinceramente no me ha convencido este formato.

      estaría bien que hicieran un nuevo curso con más pasos

      He hecho unos cuantos cursos en Platzi y nunca me había encontrado con algo tan malo. Con la calidad que tienes los cursos de Javascript este curso no se entiende nada.

      al toparte esta clase como #2 estuve tentado a rayarles la madre pero intenté buscar el verdadero inicio y creo que es la siguiente lección, por lo que vi (saltandome párrafos) la instalación del ambient eestá en el #5.

      Dejo esta nota para quien llegó al curso y se topó el mismo problema

      A la gente de platzi : Por favor corrijan el índice.

      Gracias

      Me rindo Ya no soy capaz de seguir este curso 😒

      que mal curso

      Hasta ahora esto es lo que tengo:

      Screenshot from 2020-06-21 22-35-33.png

      No entiendo proque esta es la segunda clase. El curso esta desorganizado

      Fuera bueno que el profe adjunte el esquema gráfico de la base con sus respectivas relaciones, facilitaría más el proceso

      Hey!. Acaso esto en un copy & paste??

      Tan solo inicio el curso lei unas cuantas lineas y me voy a los comentarios para ver si solo yo soy el que opina lo malo de este curso, lo hicieron a la carrera sin pensar, no dan bases ni nada malisimo el curso, no se si hay otro donde den las bases del framework la arquitectura pero ni eso indica el profesor. MUY MAL

      Que flojera de curso, no hay nada de estructura, ni una introducción al framework, ni como empezar el proyecto, ni que se va a necesitar, simplemente nada, te manda a hacer cosas por tu cuenta casi solo y le llama curso. Nunca en la vida me había topado con un curso tan pero tan malo hasta ganas de terminarlo para ponerle 0 estrellas me dan, pero me ganó la flojera

      No logro entender que paso aquí, no logro entender donde empezó... no sé cómo seguir el curso lo malo que es una limitante para terminar la carrera, estoy a dos cursos y me topo con esto es algo decepcionante, se supone que conoceremos un nuevo framework... entonces como lo instalamos? Como comenzamos, que está haciendo… No entiendo nada...

      Allí vamos pero le hace falta un poco más de orden al curso

      Donde esta la URL al código ?

      Uff. Un poco complicado pero ahí vamos.