Como crear un CRUD con Galería de Imágenes en Laravel 6.2 y Bootstrap 4 – Parte 2
En esta página:
Demo
En este Post continuaremos con la Parte anterior llamada Como crear un CRUD con Galería de Imágenes en Laravel 6.2 y Bootstrap 4 – Parte 1 en donde creamos el proyecto para este tutorial, instalamos Bootstrap 4 con sus dependencias respectivas y creamos la Base de Datos para el sistema CRUD, en esta Parte 2 crearemos los modelos, el controlador y otros detalles, vamos con este Post.
Partes
Antes de continuar con este Post, te invito a escuchar el Podcast: “Donde buscar ayuda sobre Programación”:
Spotify:
Sound Cloud:
Bien ahora continuemos con el Post: Como crear un CRUD con Galería de Imágenes en Laravel 6.2 y Bootstrap 4 – Parte 2.
Para poder acceder a los datos que se encuentra en la Base de Datos, vamos a crear un modelo, luego para unir el modelo y las vista del sistema CRUD, vamos a crear un controlador, el cual se encargará de esto.
Modelos
En la Parte 1 de este tutorial creamos 2 tablas, por ende voy a necesitar crear 2 modelos, uno se llamará Bicicletas y otro Imgbicicletas.
Bicicletas
Voy a crear un modelo llamado Bicicletas, para esto ejecuto el siguiente comando:
1 2 3 4 5 |
php artisan make:model Bicicletas Model created successfully. |
Tras ejecutar el comando anterior, se me ha creado un archivo llamado Bicicletas.php en app > Bicicletas.php
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 |
/miproyecto ├── /app ├── /Console ├── /Exceptions ├── /Http ├── /Providers ├── Bicicletas.php // Se ha creado este Archivo ├── User.php ├── /bootstrap ├── /config ├── /database ├── /node_modules ├── /public ├── /resources ├── /routes ├── /storage ├── /tests ├── /vendor ├── .editorconfig ├── .env ├── .env.example ├── .styleci.yml ├── artisan ├── composer.json ├── composer.lock ├── package.json ├── phpunit.xml ├── server.php ├── webpack.mix.js |
Abro el archivo Bicicletas.php que acabo de crear y agrego lo siguiente (En el código he colocado comentarios para explicar que hace cada línea de código):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Bicicletas extends Model { // Instancio la tabla 'bicicletas' protected $table = 'bicicletas'; // Declaro los campos que usaré de la tabla 'bicicletas' protected $fillable = ['nombre', 'precio', 'stock', 'imagenes', 'url']; // Relación One to Many (Uno a muchos), un registro puede tener muchas imágenes public function imagenesbicicletas() { return $this->hasMany('App\Imgbicicletas'); } } |
Al final del modelo puedes ver que he creado una relación One to Many (Uno a muchos) ya que un registro puede tener muchas imágenes.
Imgbicicletas
Voy a crear un modelo llamado Imgbicicletas, para esto ejecuto el siguiente comando:
1 2 3 4 5 |
php artisan make:model Imgbicicletas Model created successfully. |
Tras ejecutar el comando anterior, se me ha creado un archivo llamado Imgbicicletas.php en app > Imgbicicletas.php
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 |
/miproyecto ├── /app ├── /Console ├── /Exceptions ├── /Http ├── /Providers ├── Bicicletas.php ├── Imgbicicletas.php // Se ha creado este Archivo ├── User.php ├── /bootstrap ├── /config ├── /database ├── /node_modules ├── /public ├── /resources ├── /routes ├── /storage ├── /tests ├── /vendor ├── .editorconfig ├── .env ├── .env.example ├── .styleci.yml ├── artisan ├── composer.json ├── composer.lock ├── package.json ├── phpunit.xml ├── server.php ├── webpack.mix.js |
Abro el archivo Imgbicicletas.php que acabo de crear y agrego lo siguiente (En el código he colocado comentarios para explicar que hace cada línea de código):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Imgbicicletas extends Model { // Instancio la tabla 'img_bicicletas' protected $table = 'img_bicicletas'; // Declaro los campos que usaré de la tabla 'img_bicicletas' protected $fillable = ['nombre', 'formato', 'bicicletas_id']; // Relación Inversa (Opcional) public function bicicleta() { return $this->belongsTo('App\Bicicletas'); } } |
Al final del modelo puedes ver que he creado una relación inversa belongsTo (Pertenece a), esta es opcional y es lo inverso a One to Many.
Controlador
Ahora voy a crear el controlador de mi sistema CRUD, este lo crearé ejecutando el siguiente comando:
1 2 3 4 5 |
php artisan make:controller BicicletasController Controller created successfully. |
Después de ejecutar el comando anterior, se me ha creado un archivo llamado BicicletasController.php en app > Http > Controllers > BicicletasController.php
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 |
/miproyecto ├── /app ├── /Console ├── /Exceptions ├── /Http ├── /Controllers ├── /Auth ├── Controller.php ├── HomeController.php ├── BicicletasController.php // Se ha creado este Archivo ├── /Middleware ├── /Requests ├── Kernel.php ├── /Providers ├── Bicicletas.php ├── User.php ├── /bootstrap ├── /config ├── /database ├── /node_modules ├── /public ├── /resources ├── /routes ├── /storage ├── /tests ├── /vendor ├── .editorconfig ├── .env ├── .env.example ├── .styleci.yml ├── artisan ├── composer.json ├── composer.lock ├── package.json ├── phpunit.xml ├── server.php ├── webpack.mix.js |
Abro el archivo BicicletasController.php y empezaré agregado los siguientes Traits:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
namespace App\Http\Controllers; use App\Bicicletas; use App\Imgbicicletas; use Session; use Redirect; use App\Http\Requests; use App\Http\Controllers\Controller; use App\Http\Requests\ItemCreateRequest; use App\Http\Requests\ItemUpdateRequest; use Illuminate\Support\Facades\Validator; use DB; use Input; use Storage; use Illuminate\Support\Str; use File; class BicicletasController extends Controller { // Acá el código del Controlador } |
Ahora después de los Traits, colocaré dentro de mi clase BicicletasController, el código con las operaciones CRUD (Create, Read, Update y Delete), en el código explico con comentarios, que hace cada parte de la línea de código:
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
<?php namespace App\Http\Controllers; use App\Bicicletas; use App\Imgbicicletas; use Session; use Redirect; use App\Http\Requests; use App\Http\Controllers\Controller; use App\Http\Requests\ItemCreateRequest; use App\Http\Requests\ItemUpdateRequest; use Illuminate\Support\Facades\Validator; use DB; use Input; use Storage; use Illuminate\Support\Str; use File; class BicicletasController extends Controller { // Leer Registros (Read) public function index() { $bicicletas = Bicicletas::select('id', 'nombre', 'precio', 'stock', 'imagenes', 'url')->with('imagenesbicicletas:nombre')->get(); //$ib = Bicicletas::find(3)->imagenesbicicletas; //dd($ib); // $imagenes = Bicicletas::find(3)->imagenesbicicletas; return view('admin.bicicletas.index', compact('bicicletas')); } // Crear un Registro (Create) public function crear() { $bicicletas = Bicicletas::all(); return view('admin.bicicletas.crear', compact('bicicletas')); } // Proceso de Creación de un Registro public function store(ItemCreateRequest $request) { $bicicletas= new Bicicletas; $bicicletas->nombre = $request->nombre; $bicicletas->precio = $request->precio; $bicicletas->stock = $request->stock; $bicicletas->imagenes = date('dmyHi'); $bicicletas->url = Str::slug($request->nombre, '-'); // Acá generamos la URL amigable a partir del nombre y la guardamos en la Base de Datos $bicicletas->save(); $ci = $request->file('img'); // Validamos que el nombre y el formato de imagen esten presentes, tu puedes validar mas campos si deseas $this->validate($request, [ 'nombre' => 'required', 'img.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048' ]); // Recibimos una o varias imágenes y las guardamos en la carpeta 'uploads' foreach($request->file('img') as $image) { $imagen = $image->getClientOriginalName(); $formato = $image->getClientOriginalExtension(); $image->move(public_path().'/uploads/', $imagen); // Guardamos el nombre de la imagen en la tabla 'img_bicicletas' DB::table('img_bicicletas')->insert( [ 'nombre' => $imagen, 'formato' => $formato, 'bicicletas_id' => $bicicletas->id, 'created_at' => date("Y-m-d H:i:s"), 'updated_at' => date("Y-m-d H:i:s") ] ); } // Redireccionamos con mensaje return redirect('admin/bicicletas')->with('message','Guardado Satisfactoriamente !'); } // Leer un Registro específico (Leer) public function show($id) { // } // Actualizar un registro (Update) public function actualizar($id) { $bicicletas = Bicicletas::find($id); $imagenes = Bicicletas::find($id)->imagenesbicicletas; return view('admin/bicicletas.actualizar', compact('imagenes'), ['bicicletas' => $bicicletas]); } // Proceso de Actualización de un Registro (Update) public function update(ItemUpdateRequest $request, $id) { $bicicletas= Bicicletas::find($id); $bicicletas->nombre = $request->nombre; $bicicletas->precio = $request->precio; $bicicletas->stock = $request->stock; $bicicletas->save(); $ci = $request->file('img'); // Si la variable '$ci' no esta vacia, actualizamos el registro con las nuevas imágenes if(!empty($ci)){ // Validamos que el nombre y el formato de imagen esten presentes, tu puedes validar mas campos si deseas $this->validate($request, [ 'nombre' => 'required', 'img.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048' ]); // Recibimos una o varias imágenes y las actualizamos foreach($request->file('img') as $image) { $imagen = $image->getClientOriginalName(); $formato = $image->getClientOriginalExtension(); $image->move(public_path().'/uploads/', $imagen); // Actualizamos el nuevo nombre de la(s) imagen(es) en la tabla 'img_bicicletas' DB::table('img_bicicletas')->insert( [ 'nombre' => $imagen, 'formato' => $formato, 'bicicletas_id' => $bicicletas->id, 'created_at' => date("Y-m-d H:i:s"), 'updated_at' => date("Y-m-d H:i:s") ] ); } } // Redireccionamos con mensaje Session::flash('message', 'Editado Satisfactoriamente !'); return Redirect::to('admin/bicicletas'); } // Eliminar un Registro public function eliminar($id) { $bicicletas = Bicicletas::find($id); // Selecciono las imágenes a eliminar $imagen = DB::table('img_bicicletas')->where('bicicletas_id', '=', $id)->get(); $imgfrm = $imagen->implode('nombre', ','); //dd($imgfrm); // Creamos una lista con los nombres de las imágenes separadas por coma $imagenes = explode(",", $imgfrm); // Recorremos la lista de imágenes separadas por coma foreach($imagenes as $image){ // Elimino la(s) imagen(es) de la carpeta 'uploads' $dirimgs = public_path().'/uploads/'.$image; // Verificamos si la(s) imagen(es) existe(n) y procedemos a eliminar if(File::exists($dirimgs)) { File::delete($dirimgs); } } // Borramos el registro de la tabla 'bicicletas' Bicicletas::destroy($id); // Borramos las imágenes de la tabla 'img_bicicletas' $bicicletas->imagenesbicicletas()->delete(); // Redireccionamos con mensaje Session::flash('message', 'Eliminado Satisfactoriamente !'); return Redirect::to('admin/bicicletas'); } // Eliminar imagen de un Registro public function eliminarimagen($id, $bid) { $bicicletas = Imgbicicletas::find($id); $bi = $bid; // Elimino la imagen de la carpeta 'uploads' $imagen = Imgbicicletas::select('nombre')->where('id', '=', $id)->get(); $imgfrm = $imagen->implode('nombre', ', '); //dd($imgfrm); Storage::delete($imgfrm); Imgbicicletas::destroy($id); // Redireccionamos con mensaje Session::flash('message', 'Imagen Eliminada Satisfactoriamente !'); return Redirect::to('admin/bicicletas/actualizar/'.$bi.''); } // Detalles del Producto public function detallesproducto($id) { // Seleccionar un registro por su 'id' $bicicletas = Bicicletas::where('id','=', $id)->firstOrFail(); // Seleccionamos las imágenes por su 'id' $imagenes = Bicicletas::find($id)->imagenesbicicletas; return view('admin/bicicletas.detallesproducto', compact('bicicletas', 'imagenes')); } } |
Bien en esta Parte 2, hemos creado el Controlador que procesará las tareas CRUD y los Modelos que me permitirá acceder a los datos de la tabla bicicletas e img_bicicletas de 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 de este Tutorial crearemos las rutas y las primeras vistas del sistema CRUD, entre otros detalles.
- No olvides que debemos usar 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.
- Laravel Tutoriales
- 07-03-2020
- 14-05-2020
- Crear un Post - Eventos Devs - Foro