Creando una Aplicación Web similar a SoundCloud con Ruby on Rails 6 y Angular 10 – Parte 7
En esta página:
Si este tutorial también tendrá muchas partes y es que quiero que conozcas todos los detalles posibles para la creación de este proyecto, en la parte anterior terminamos de crear los controladores para las vistas administrables y en esta parte 7 vamos a comenzar a crear sus vistas o interfaces UI y así sucesivamente crearemos las que siguen, bien pongamos manos a la obra, vamos con este Post.
Partes
Antes de continuar te invito a leer los siguientes artículos:
- Que es Ruby on Rails (RoR) y otros detalles
- Tu primer Hola Mundo con Ruby on Rails
- Como crear un CRUD con Ruby on Rails 6 y Bootstrap 4 – Parte 1
- Como Integrar React JS (16.13.1) en Ruby on Rails (6.0.3.2)
- Lee más artículos en la categoría Ruby on Rails.
Asimismo, te invito a escuchar el Podcast: “Si No Tienes Experiencia Para Un Puesto De Trabajo, Créala !”:
Spotify | SoundCloud | Apple Podcasts |
Bien ahora continuemos con el Post: Creando una Aplicación Web similar a SoundCloud con Ruby on Rails 6 y Angular 10 – Parte 7.
Es importante recordar que estamos desarrollando la parte administrable que gestiona todos los datos de la aplicación y esta parte administrable la mayoría de usuarios públicos no la podemos ver. Si hacemos una revisión en la plataforma SoundCloud solo podemos ver ciertas funciones como propietario de una cuenta de SounCloud, entre las opciones que podemos ver esta la página de configuración, la pagina para subir un archivo de audio, estadísticas, mi biblioteca, etc.
Pero la vista administrable solo los ven los administradores o encargados de gestionar la plataforma SoundCloud y esta parte administrable es la que venimos desarrollando. Más adelante desarrollaremos las vistas públicas como la página de configuración, la pagina para subir un archivo de audio, mi biblioteca, etc.
En la Parte 1 de este tutorial instalamos Bootstrap 4 con sus dependencias necesarias (jQuery y Popper JS) y con este Framework vamos crear la mayoría de partes de la interface Administrativa. Para las tareas Asíncronas y dinámicas en las vistas HTML usaremos Angular.
Layout UI (Administrador)
Cuando creamos el proyecto con Rails 6, este nos creo un archivo layout llamado application.html.erb en soundcloudapp > view > layouts > application.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/soundcloudapp ├── /app ├── /assets ├── /channels ├── /controllers ├── /helpers ├── /javascript ├── /jobs ├── /mailers ├── /models ├── /views ├── /admin ├── /layouts ├── application.html.erb // Abro este Archivo ├── mailer.html.erb ├── mailer.text.erb ├── /bin ├── /config ├── /db ├── /lib ├── /log ├── /public ├── /storage ├── /test ├── /tmp ├── /vendor ├── .gitignore ├── .ruby-version ├── config.ru ├── Gemfile ├── Gemfile.lock ├── package.json ├── Rakefile ├── Gemfile.lock ├── README.md |
Este archivo application.html.erb es un archivo de plantilla que usaremos en todas las vistas de nuestro administrador, esto es genial porque si queremos hacer un cambio que se aplique a todas nuestras vistas administrativas, solo debemos editar el archivo application.html.erb
Y pospuesto cada vista administrativa va tener en su interior su propio contenido independiente que será diferente a todos los demás.
Abro el archivo application.html.erb y agrego lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
<!doctype html> <html lang="es"> <head> <title>Como integrar Ruby on Rails 5 y Bootstrap 4 </title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="https://blog.nubecolectiva.com/wp-content/uploads/2018/08/faviconcc.png"> <!-- Con estas 2 líneas llamamos a los archivos CSS y Javascript de Bootstrap y demás --><%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %><%#= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <!-- Utilidad CSS de Bootstrap externa (No es necesario, sin esta línea ya debería funcionarte Bootstrap) --> <link href="https://getbootstrap.com/docs/4.0/examples/jumbotron/jumbotron.css" rel="stylesheet"> </head> <body> <!-- Menú Superior --> <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark"> <a class="navbar-brand" href="#">SoundCloud App</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarsExampleDefault"> <ul class="navbar-nav mr-auto"> <li class="nav-item"> <a class="nav-link" href="#">Sponsors </a> </li> <li class="nav-item"> <a class="nav-link" href="#">Recursos</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Soporte</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Prensa</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Marketing</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Ventas</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Email</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="https://example.com" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Más</a> <div class="dropdown-menu" aria-labelledby="dropdown01"> <a class="dropdown-item" href="#">Opción 1</a> <a class="dropdown-item" href="#">Opción 2</a> <a class="dropdown-item" href="#">Opción 3</a> </div> </li> </ul> <form class="form-inline my-2 my-lg-0"> <input class="form-control mr-sm-2" type="text" placeholder="Buscar" aria-label="Buscar" required> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Buscar</button> </form> </div> </nav> <!-- Menú Lateral Izquierdo --> <div class="container-fluid"> <div class="row"> <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse"> <div class="sidebar-sticky pt-3"> <ul class="nav flex-column"> <li class="nav-item"> <a class="nav-link" href="#"> <i data-feather="speaker"></i> Canciones (Usuarios) </a> </li> </ul> </div> </nav> <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4"> <!-- Aca renderizamos los elementos de cada módulo del administrador, dentro de la etiqueta 'yield' --> <%= yield %> </main> </div> </div> <footer class="footer mt-5 py-3"> <div class="container"> <span class="text-muted">SoundCloud App Ⓒ</span> </div> </footer> <!-- Iconos (Feather) --> <script src="https://unpkg.com/feather-icons"></script> <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> <script type="text/javascript"> feather.replace() </script> </body> </html> |
Si voy a la ruta http://localhost:3000/admin/cancionesusuarios/index en el navegador, debería ver lo siguiente:
Ahora que tenemos lista nuestra plantilla o layout, pasaremos a crear las vistas del administrador sin problemas.
Canciones de Usuarios UI (Administrador)
Para este módulo vamos a crear una vista principal en donde se listarán todas las canciones de un usuario, también otra vista que contendrá un formulario para agregar canciones para un usuario y otra vista para editar las canciones de un usuario. Para la tarea de eliminar simplemente lo haremos mediante un botón que diga Eliminar en la vista principal en donde se muestran todas las canciones de los usuarios.
Vista Principal (Canciones de Usuarios)
Abro el archivo llamado index.html.erb que se encuentra en soundcloudapp > view > admin > cancionesusuarios > index.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/soundcloudapp ├── /app ├── /assets ├── /channels ├── /controllers ├── /helpers ├── /javascript ├── /jobs ├── /mailers ├── /models ├── /views ├── /admin ├── /cancionesusuarios ├── actualizar.html.erb ├── crear.html.erb ├── index.html.erb // Abro este Archivo ├── leer.html.erb ├── /configuracion ├── /historialreproducciones ├── /usuarios ├── /layouts ├── /bin ├── /config ├── /db ├── /lib ├── /log ├── /public ├── /storage ├── /test ├── /tmp ├── /vendor ├── .gitignore ├── .ruby-version ├── config.ru ├── Gemfile ├── Gemfile.lock ├── package.json ├── Rakefile ├── Gemfile.lock ├── README.md |
Borro el contenido que hay en el interior del archivo index.html.erb y agrego lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">Canciones (Usuarios)</h1> </div> <div class="mb-3"> <button type="button" class="btn btn-success">Agregar <i data-feather="plus-square"></i> </button> </div> <div class="table-responsive"> <table class="table table-striped table-sm text-center"> <thead> <tr> <th>#</th> <th>Usuario</th> <th>Fecha Registro</th> <th>Nro. Canciones</th> <th>Acciones</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>pepetoro</td> <td>12-10-2020</td> <td>5</td> <td> <div class="btn-group" role="group" aria-label="Basic example"> <button type="button" class="btn btn-secondary">Editar <i data-feather="edit"></i> </button> <button type="button" class="btn btn-secondary">Eiminar <i data-feather="x-square"></i> </button> </div> </td> </tr> <tr> <td>1</td> <td>rlsongs</td> <td>09-05-2018</td> <td>10</td> <td> <div class="btn-group" role="group" aria-label="Basic example"> <button type="button" class="btn btn-secondary">Editar <i data-feather="edit"></i> </button> <button type="button" class="btn btn-secondary">Eiminar <i data-feather="x-square"></i> </button> </div> </td> </tr> <tr> <td>1</td> <td>pizza21</td> <td>10-02-2021</td> <td>3</td> <td> <div class="btn-group" role="group" aria-label="Basic example"> <button type="button" class="btn btn-secondary">Editar <i data-feather="edit"></i> </button> <button type="button" class="btn btn-secondary">Eiminar <i data-feather="x-square"></i> </button> </div> </td> </tr> </tbody> </table> </div> |
Y si voy nuevamente a la ruta http://localhost:3000/admin/cancionesusuarios/index en el navegador, debería ver lo siguiente:
Los datos que puedes ver en la imagen anterior son datos para maquetar o estructurar la vista de Canciones del Usuario, mas adelante usaremos datos desde la base de datos.
Agregar (Canciones de Usuarios)
Esta vista servirá para agregar canciones para un usuario determinado, abro el archivo llamado crear.html.erb que se encuentra en soundcloudapp > view > admin > cancionesusuarios > crear.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/soundcloudapp ├── /app ├── /assets ├── /channels ├── /controllers ├── /helpers ├── /javascript ├── /jobs ├── /mailers ├── /models ├── /views ├── /admin ├── /cancionesusuarios ├── actualizar.html.erb ├── crear.html.erb // Abro este Archivo ├── index.html.erb ├── leer.html.erb ├── /configuracion ├── /historialreproducciones ├── /usuarios ├── /layouts ├── /bin ├── /config ├── /db ├── /lib ├── /log ├── /public ├── /storage ├── /test ├── /tmp ├── /vendor ├── .gitignore ├── .ruby-version ├── config.ru ├── Gemfile ├── Gemfile.lock ├── package.json ├── Rakefile ├── Gemfile.lock ├── README.md |
Borro el contenido que hay en el archivo crear.html.erb y agrego lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
<!-- Breadcrumb --> <nav aria-label="breadcrumb" class="mt-4"> <ol class="breadcrumb"> <li class="breadcrumb-item"><a href="#">Canciones (Usuarios)</a></li> <li class="breadcrumb-item active" aria-current="page">Agregar</li> </ol> </nav> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">Agregar - Canciones (Usuarios)</h1> </div> <!-- Formulario --> <form> <div class="form-group row"> <div class="col-sm-6"> <label for="nombre" class="font-weight-bold">Nombre</label> <input type="text" class="form-control" id="nombre" name="nombre" aria-describedby="nombreHelp" required> <small id="nombreHelp" class="form-text text-muted">Ejemplo: La Noche Linda - Pedro Rojas</small> </div> <div class="col-sm-6"> <label for="genero" class="font-weight-bold">Género</label> <select class="form-control" id="genero" name="genero" required> <option>Seleccionar</option> <option>Género 1</option> <option>Género 2</option> <option>Género 3</option> <option>Género 4</option> <option>Género 5</option> </select> <small id="generoHelp" class="form-text text-muted">Ejemplo: Dance</small> </div> </div> <div class="form-group row"> <div class="col-sm-6"> <label for="nombre" class="font-weight-bold">Foto o Imagen (Portada)</label> <div class="custom-file"> <input type="file" class="custom-file-input" id="fotoportada" name="fotoportada" lang="es" aria-describedby="fotoportadaHelp" required> <label class="custom-file-label" for="customFileLang">Seleccionar Archivo</label> </div> <small id="fotoportadaHelp" class="form-text text-muted">Formatos: JPG, PNG y BMP</small> </div> <div class="col-sm-6"> <label for="archivo" class="font-weight-bold">Archivo (Audio)</label> <div class="custom-file"> <input type="file" class="custom-file-input" id="archivo" name="archivo" lang="es" aria-describedby="fotoportadaHelp" required> <label class="custom-file-label" for="customFileLang">Seleccionar Archivo</label> </div> <small id="archivoHelp" class="form-text text-muted">Formatos: MP3 y WAW</small> </div> </div> <div class="form-group row"> <div class="col-sm-6"> <label for="usuario" class="font-weight-bold">Usuario</label> <select class="form-control" id="usuario" name="usuario" required> <option>Seleccionar</option> <option>Usuario 1</option> <option>Usuario 2</option> <option>Usuario 3</option> <option>Usuario 4</option> <option>Usuario 5</option> </select> <small id="usuarioHelp" class="form-text text-muted">Ejemplo: pepetoro</small> </div> </div> <button type="submit" class="btn btn-primary px-4 float-left">Guardar</button> </form> |
Si voy a la ruta http://localhost:3000/admin/cancionesusuarios/crear en el navegador, debería ver lo siguiente:
En el formulario anterior tenemos el campo usuario, este campo será alimentado por la tabla usuarios que creamos anteriormente. Asimismo tenemos un campo llamado genero, este campo también lo podemos alimentar desde una tabla que por ejemplo se llame generos. Pero para no expandirme tanto con el tutorial, escribiré los nombres de los géneros manualmente.
Actualizar (Canciones de Usuarios)
Esta vista servirá para editar las canciones de un usuario determinado, abro el archivo llamado actualizar.html.erb que se encuentra en soundcloudapp > view > admin > cancionesusuarios > actualizar.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/soundcloudapp ├── /app ├── /assets ├── /channels ├── /controllers ├── /helpers ├── /javascript ├── /jobs ├── /mailers ├── /models ├── /views ├── /admin ├── /cancionesusuarios ├── actualizar.html.erb // Abro este Archivo ├── crear.html.erb ├── index.html.erb ├── leer.html.erb ├── /configuracion ├── /historialreproducciones ├── /usuarios ├── /layouts ├── /bin ├── /config ├── /db ├── /lib ├── /log ├── /public ├── /storage ├── /test ├── /tmp ├── /vendor ├── .gitignore ├── .ruby-version ├── config.ru ├── Gemfile ├── Gemfile.lock ├── package.json ├── Rakefile ├── Gemfile.lock ├── README.md |
Borro el contenido que hay en el archivo actualizar.html.erb y agrego lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
<!-- Breadcrumb --> <nav aria-label="breadcrumb" class="mt-4"> <ol class="breadcrumb"> <li class="breadcrumb-item"><a href="#">Canciones (Usuarios)</a></li> <li class="breadcrumb-item active" aria-current="page">Agregar</li> </ol> </nav> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">Actualizar - Canciones (Usuarios)</h1> </div> <div class="accordion" id="accordionExample"> <div class="card"> <div class="card-header" id="headingOne"> <h2 class="mb-0"> <button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> Canción: La Noche Linda - Pedro Rojas </button> </h2> </div> <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordionExample"> <div class="card-body"> <!-- Formulario --> <form> <div class="form-group row"> <div class="col-sm-6"> <label for="nombre" class="font-weight-bold">Nombre</label> <input type="text" class="form-control" id="nombre" name="nombre" aria-describedby="nombreHelp" required> <small id="nombreHelp" class="form-text text-muted">Ejemplo: La Noche Linda - Pedro Rojas</small> </div> <div class="col-sm-6"> <label for="genero" class="font-weight-bold">Género</label> <select class="form-control" id="genero" name="genero" required> <option>Seleccionar</option> <option>Género 1</option> <option>Género 2</option> <option>Género 3</option> <option>Género 4</option> <option>Género 5</option> </select> <small id="generoHelp" class="form-text text-muted">Ejemplo: Dance</small> </div> </div> <div class="form-group row"> <div class="col-sm-6"> <label for="nombre" class="font-weight-bold">Foto o Imagen (Portada)</label> <div class="custom-file"> <input type="file" class="custom-file-input" id="fotoportada" name="fotoportada" lang="es" aria-describedby="fotoportadaHelp" required> <label class="custom-file-label" for="customFileLang">Seleccionar Archivo</label> </div> <small id="fotoportadaHelp" class="form-text text-muted">Formatos: JPG, PNG y BMP</small> </div> <div class="col-sm-6"> <label for="archivo" class="font-weight-bold">Archivo (Audio)</label> <div class="custom-file"> <input type="file" class="custom-file-input" id="archivo" name="archivo" lang="es" aria-describedby="fotoportadaHelp" required> <label class="custom-file-label" for="customFileLang">Seleccionar Archivo</label> </div> <small id="archivoHelp" class="form-text text-muted">Formatos: MP3 y WAW</small> </div> </div> <div class="form-group row"> <div class="col-sm-6"> <label for="usuario" class="font-weight-bold">Usuario</label> <select class="form-control" id="usuario" name="usuario" required> <option>Seleccionar</option> <option>Usuario 1</option> <option>Usuario 2</option> <option>Usuario 3</option> <option>Usuario 4</option> <option>Usuario 5</option> </select> <small id="usuarioHelp" class="form-text text-muted">Ejemplo: pepetoro</small> </div> </div> <button type="submit" class="btn btn-primary px-4 float-left">Guardar</button> </form> </div> </div> </div> <div class="card"> <div class="card-header" id="headingTwo"> <h2 class="mb-0"> <button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"> Canción 2 </button> </h2> </div> <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample"> <div class="card-body"> Some placeholder content for the second accordion panel. This panel is hidden by default. </div> </div> </div> <div class="card"> <div class="card-header" id="headingThree"> <h2 class="mb-0"> <button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree"> Canción 3 </button> </h2> </div> <div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordionExample"> <div class="card-body"> And lastly, the placeholder content for the third and final accordion panel. This panel is hidden by default. </div> </div> </div> </div> |
Si voy a la ruta http://localhost:3000/admin/cancionesusuarios/actualizar en el navegador, debería ver lo siguiente:
En la imagen anterior he colocado unos collapse de Bootstrap 4 para poder editar cada canción del usuario.
Bien hasta aquí he creado las vistas del módulo Canciones del Usuario y más adelante las integraremos con la base de datos.
Ten Paciencia, lo que quiero es que entiendas todo el proceso para Crear este Proyecto y no llenarte el capitulo de mucho contenido porque te puedes marear y no tendrás un óptimo aprendizaje.
Nota (s)
- En la siguiente parte crearemos la interface administrativa del módulo Configuración.
- No olvides que debemos utilizar la tecnología para hacer cosas buenas por el mundo.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.
- Ruby on Rails Tutoriales
- 09-10-2021
- 21-10-2021
- Crear un Post - Eventos Devs - Foro
Social
Redes Sociales (Developers)
Redes Sociales (Digital)