Top Banner
102

Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Mar 17, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,
Page 2: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

1.1

1.2

1.3

1.4

1.5

1.6

1.7

1.8

1.9

1.10

1.11

1.12

1.13

1.14

1.15

1.16

1.17

1.18

1.19

TableofContentsIntroduction

Introducción

Capítulo1.Instalación

Capítulo2.PSR-4ynamespaces

Capítulo3.Conexiónconbasededatos

Capítulo4.EstructuradeunproyectoenLaravel

Capítulo5.JSON

Capítulo6.MigracionesySeeders

Capítulo7.ModelosyusodeEloquent

Capítulo8.Modelfactories(Poblarbasededatosconfaker)

Capítulo9.Enrutamientobásico

Capítulo10.VistasymotordeplantillasBlade

Capítulo11.Controladores

Capítulo12.ValidacionesenLaravel

Capítulo13.Middlewares

AnexoA.HTML5

AnexoB.CSS

AnexoC.CRUDconLaravel

AnexoD.ComponenteDatatable

2

Page 3: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

IntroducciónaLaravel5Laravelesunframeworkparaaplicacioneswebconsintaxisexpresivayelegante.Creemosqueeldesarrollodebeserunaexperienciaagradableycreativaparaqueseaverdaderamenteenriquecedora.Laravelbuscaeliminarelsufrimientodeldesarrollofacilitandolastareascomunesutilizadasenlamayoríadelosproyectosweb,comolaautenticación,enrutamiendo,sesionesyalmacenamientoencaché.

LaravelesunframeworkparaellenguajedeprogramaciónPHP.AunquePHPesconocidoportenerunasintaxispocodeseable,esfácildeusar,fácildedesplegaryselepuedeencontrarenmuchosdelossitioswebmodernosqueusasdíaadía.Laravelnosoloofreceatajosútiles,herramientasycomponentesparaayudarteaconseguireléxitoentusproyectosbasadosenweb,sinoquetambiénintentaarreglaralgunadelasflaquezasdePHP.

Laraveltieneunasintaxisbonita,semánticaycreativa,quelepermitedestacarentrelagrancantidaddeframeworksdisponiblesparaellenguaje.HacequePHPseaunplacer,sinsacrificarpotenciayeficiencia.Essencillodeentender,permitemucholamodularidaddecódigolocuálesbuenoenlareutilizacióndecódigo.

BeneficiosdeLaravel

1. IncluyeunORM:AdiferenciadeCodeIgniter,LaravelincluyeunORMintegrado.Porlocualnodebesinstalarabsolutamentenada.

2. Bundles:existenvariospaquetesqueextiendenaLaravelytedanfuncionalidadesincreíbles..

3. Programasdeunaformaeleganteyeficiente:Nomáscódigobasuraoespaguettiquenoseentienden,aprenderásaprogramar‘conclase’yordenartucódigodemaneradequesealomásre-utilizableposible.

4. ControlaslaBDdesdeelcódigo:Puedesteneruncontroldeversionesdeloquehacesconella.Aestosellamanmigrations,esunaexcelenteherramienta,porquepuedesmanejartododesdetuIDE,inclusivemontardatosentustablas.

5. DasoporteaPHP5.3.

6. Rutaselegantesyseguras:UnamismarutapuederesponderdedistintomodoaunmétodoGEToPOST.

7. CuentaconsupropiomotordeplatillasHTML.

Introduction

3

Page 4: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

8. Seactualizafacilmentedesdelalíneadecomandos:Elframeworkesactualizableutilizandocomposerupdateylisto,nadadedescargarunZIPyestarremplazando.

9. Cuentaconunacomunidadactivaquedaapoyorápidoalmomentodequelonecesitas.

Requerimientosiniciales

ParaempezaratrabajarconLaravelesnecesariocumplirconlossiguientesrequisitosiniciales:

Unentornodedesarrolloweb:Apache,IIS,NginxPHP5.3osuperiorBasededatos:MySQL,Sqlite,PostgresqlosqlserverLibreríasphp:Mcrypt

ComposeresunaherramientaparaadministracióndedependenciasenPHP.Tepermitedeclararlaslibreríasdelascuálestuproyectodependeonecesitayéstelasinstalaenelproyectoporti.

Composernoesunadministradordepaquetes.Sí,éltratacon"paquetes"o"librerías",perolasgestionaenfuncióndecadaproyectoynoinstalanadaglobalmenteentuequipo,porlocualsoloadministralasdependenciasdelmismo.

ComposerusaunarchivodentrodetuproyectodeLaravelparapoderadministrarlasdependenciaselcualsellama:composer.json.EsteusaunformatoJSONelcualseexplicarámásadelante,unejemplodeélsemuestraeestaimagen:

Introduction

4

Page 5: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Ahora,composernoselimitaasuusounicamenteconproyectosLaravel,sinoqueenLaravelelusodecomposernosfacilitaelcontroldedependenciasyenlaactualizacióndecadaunacomoseexplicóanteriormente.ParaestecursosetrabajaráconestearchivopueseselquesevaacrearalmomentodeinstalarLaravel.

Enestearchivopodemosobservarciertoordenenelacomododelainformación.

"name":Enestasecciónsedescribeelnombredelusuariopropietariodelproyectoseguidodelnombredelrepositorioquealojaelproyectoseparadosporunabarra(/).

"description":Sirveparafacilitarunabrevedescripcióndelpaquete.Debemossermuyclarosybrevessideseamoscolocarunadescripcióndenuestropaquete.

"keywords":Estaspalabrasclavessonunamatrizdecadenasusadaspararepresentartupaquete.Sonsimilaresaetiquetasenunaplataformadeblogsy,esencialmente,sirvenalmismopropósito.Lasetiquetasteofrecenmetadatosdebúsquedaparacuandotupaquetesealistadoenunrepositorio.

"homepage":Laconfiguracióndelapáginaesútilparapaquetesquevanaserdecódigolibre.PuedesusarestapáginaparaelproyectooquizáparalaURLdelrepositorio.Loquecreasqueesmásinformativo.

"license":Situpaqueteestápensadoparaserredistribuido,querrásofrecerunalicenciaconél.Sinunalicenciamuchosprogramadoresnopodránusarelpaqueteporrestriccioneslegales.Escogeunalicenciaqueseajusteatusrequisitos,peroquenoseamuyrestrictivaparaaquellosqueesperanusartucódigo.ElproyectodeLaravelusalalicenciaMITqueofrecegranlibertad.

"authors":ofreceinformaciónsobrelosautoresdelpaquete,ypuedeserútilparaaquellosusuariosquequierancontactarconelautoroautores.Tenencuentaquelaseccióndeautorespermiteunamatrizdeautoresparapaquetescolaborativos.

Gestordedependencias

Unadelasopcionesinteresantesdelarchivocomposer.jsoneselcampo“require”,enelseagregancomounarregloelnombredelospaquetesquequeremosincluirennuestroproyectoseguidodelaversióndecadadependencia.

Alfinalcuandosehanagregadotodaslasdependenciasquequeremosparanuestroproyectoentoncessolobastaconusarelsiguientecomandoennuestraconsola:

composerinstall

Introduction

5

Page 6: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Conestoleindicamosacomposerquedebedescargarnuestrasdependenciasylasdependenciasdeestasdependenciasparasatisfacerlasnecesidadesdenuestroproyecto.Paramásinformaciónsobrecomposer,suscamposysuformadeusopodemosconsultarsupáginaoficialhttps://getcomposer.org/doc/lacuálseencuentraeninglés.

AprendermássobreHTML5ParaprofundizarunpocomásenHTML5esrecomendableeltutorialdew3schools.

Introduction

6

Page 7: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Preparandonuestroentornodetrabajo.Laravelnecesitaunservidorweb.NoimportacuálseaperolamayoríadelacomunidadusaApacheoNginxyhacerlomismotepondrálascosasmásfácilesalahoradebuscarayudasilanecesitas.

InstalacióndeXAMPP(Windows)XAMPPesunprogramaquenosofreceunadistribucióndeApache,MySQL,PHPyPerlmuysimpledeinstalar,administraryutilizar.Podemosdescargarloaquí.

InstalacióndeLAMP(Linux)LAMPeselconjuntodeaplicacionesApache,MySQL,PHPoPythonenentornosLinuxquenosfacilitaneldesarrollodesistemas.

EnUbuntuoderivadaspodemosinstalarloconlossiguientescomandos:

sudoapt-getupdate

sudoapt-getupgrade

sudoapt-getinstalllamp-server^

sudoapt-getinstallphp5-mcrypt

sudophp5enmodmcrypt

DespuesdetenerinstaladonuestroServidorweb,esnecesarioinstalarcomposerelcuálesungestordedependenciasphpmuyútilydelcuálsehablarámástarde.

Instalacióndecomposer(Windows)LaformamássencilladeinstalarComposerentuordenadorWindowsconsisteendescargaryejecutarelarchivoComposer-Setup.exe,queinstalalaversiónmásrecientedeComposeryactualizaelPATHdetuordenadorparaquepuedasejecutarComposersimplementeescribiendoelcomandocomposer.

Instalacióndecomposer(Linux)

Capítulo1.Instalación

7

Page 8: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Enubuntubastaráconejecutarlossiguientescomandosenlaterminal.

sudoapt-getinstallcurl

curl-sShttps://getcomposer.org/installer|php

sudomvcomposer.phar/usr/local/bin/composer

sudoecho'PATH=$PATH:~/.composer/vendor/bin'>>~/.profile

InstalacióndeLaravelExistendiferentesformasdeinstalarlaravelennuestracomputadora.

PodemosclonarelrepositorioLaraveldegithub.Usandoelinstalador:

composerglobalrequire"laravel/installer=~1.1"

laravelnewProyecto

Usandocomposer:

composercreate-projectlaravel/laravel--prefer-distProyecto

Unavezinstaladolaravelesrecomendablesituarseenlaraízdelproyectoyejecutar:

composerupdate

phpartisankey:generate

phpartisanapp:nameCurso

Capítulo1.Instalación

8

Page 9: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

PSR-4ynamespaces

¿QuéesPSR-4?

Esunaespecificaciónparalaautocargadeclasesdesdelarutadelosarchivos.Describedóndeseencuentranubicadoslosarchivosqueseránautocargados.PSR-4haceusodenamespacesparadistinguirunaclasedeotra,estoesdegranayudacuandoocupamoslibreríasdetercerosporqueenmuchasocacionesexistiránclasesconelmismonombrequelasnuestrasypodríansobreescribirseousarunaquenoqueremos.

PSR-4fuecreadaporelgrupodeinteroperabilidaddePHP,elloshantrabajadoenlacreacióndeespecificacionesdedesarrolloparaestelenguajeparaqueestandarizemosdiferentesprocesos,comoesenestecasoelcomonombrarlasclasesdenuestroproyectoyhacerusodeellas.

UsarespecificacionesPSR-4noesobligatorioysuusopuedesercompletooparcial,aunqueesrecomendablenoomitirloporqueaComposerlepermitecargarnuestrasclasesautomaticamente.

¿Quéesunautoloader?

AparecierondesdelaversióndePHP5ynospermiteencontrarclasesparaPHPcuandollamamoslasfuncionesnew()oclass_exists().Deestaformanotenemosqueseguirhaciendousoderequire()oinclude().

PSR-4nospermitedefinirnamespacesdeacuerdoalarutadelosarchivosdelasclases,esdecir,sitenemosunaclase"Pdf"eneldirectorioClases/Templates/,eseserásunamespace.Podemoshacerunsimilconelimportdejava.

ElnamespacedeClases/Templatesquedaríadelasiguienteforma:Clases\Templates\Pdf.php

ParausarPSR-4encomposerpodemosdefinirelnamespacedenuestraaplicaciónyeldirectoriodóndeseránalojadaslasclases,porejemplo:

{

"autoload":{

"psr-4":{

"Taller\\":"app/"

}

}

}

Capítulo2.PSR-4ynamespaces

9

Page 10: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Parausarlosnamespacesdentrodenuestrosarchivosphpbastaconreferenciarlosdelasiguienteforma:

useTaller\Clase;

¿Quéesclassmap?

Esunautoloaderquenospermiteregistrarnuestrasclasesparapoderocuparlassinnecesidaddeunnamespace,ladesventajarespectoaPSR-4eslacolisióndeclasesconmismonombre,laprincipalventajaeslarápidezdeautocargadeclases.Otroinconvenientedeusarclassmapesquedebemosejecutarconstantenteelcomando"composerdump-autoload"porcadaclasenuevaeneldirectorioqueindiquemosotengamosregistradoenelarchivo"composer.json".

Ejemplo:

{

"classmap":[

"database"

],

}

Capítulo2.PSR-4ynamespaces

10

Page 11: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

ConexiónconbasesdedatosLaraveltienesoporteparalosmotoresdebasesdedatosmáspopularescomo:

MySQLPostgresqlSQLite3SQLServer

VeremoscomoutilizarMySQLconlaravel.

Dentrodelarchivodatabase.phpeneldirectorioconfigconfiguramoseldriverdelaconexión,pordefectovendráconmysql,siqueremoscambiarloporotromotordebasededatostendremosquecambiarelvalormysqlporsqlite,pgsql,sqlsrv.

'default'=>env('DB_CONNECTION','mysql')

Tendremosqueconfigurarelarchivo.envubicadoenlaraízdelproyecto.

DB_HOST=localhost

DB_DATABASE=curso

DB_USERNAME=root

DB_PASSWORD=12345

Unavezquetengamostodoconfigurado,nosdirigimosalaterminalyejecutamoselcomandophpartisanmigrateparacrearlasmigraciones,sitodohasalidobientendremosqueverlastablas:

migrationspassword_resetsusers

SieresunapersonacuriosahabrásnotadoqueelnombredelastablasenLaravelsiempresonescritasenplural,estonoesporpurocapricho,espartedeunaconvención:Convencióndelaconfiguración,dichaconvenciónlepermiteaLaravelhacermagíapornosotros,nosevitarealizarconfiguraciónypasosextrasdelaasociacióndeModeloscontablasentreotrascosas.

Capítulo3.Conexiónconbasededatos

11

Page 12: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

EstructuradeunproyectoenLaravelTodoslosproyectosnuevosenLaravel5.1tienenlasiguienteestructuradedirectorios:

app/bootstrap/config/database/public/resources/storage/tests/vendor/.env.env.example.gitattributes.gitignoreartisancomposer.jsoncomposer.lockgulpfile.jspackage.jsonphpspec.ymlphpunit.xmlreadme.mdserver.php

Acontinuacióndescribiremoslosdirectoriosyarchivosmásimportantesparaquenosayudenaentendermáselfuncionamientodelframework.

Eldirectorioapp

Appesusadoparaofrecerunhogarpordefectoatodoelcódigopersonaldetuproyecto.Esoincluyeclasesquepuedanofrecerfuncionalidadalaaplicación,archivosdeconfiguraciónymás.Esconsideradoeldirectoriomásimportantedenuestroproyectoyaqueesenelquemástrabajaremos.

EldirectorioapptieneasuvezotrossubdirectoriosimportantesperounodelosmásutilizadoseseldirectorioHttpenelcuálubicaremosnuestrosControllers,MiddlewaresyRequestsensuscarpetascorrespondientes,ademásdentrodelsubdirectorioHttp

Capítulo4.EstructuradeunproyectoenLaravel

12

Page 13: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

encontremostambiénelarchivoroutes.phpdondeescribiremoslasrutasdelaaplicación.

AniveldelaraízdeldirectorioappencontraremoselmodeloUser.php,losmodeloscomunmenteseubicaránaniveldelaraízdelacarpetaappaunqueigualesposibleestructurarlosdelaformaquequeramos,porejemplo,enunacarpetallamadaModels.

Eldirectorioconfig

Laconfiguracióntantoparaelframeworkcomoparatuaplicaciónsemantieneenestedirectorio.LaconfiguracióndeLaravelexistecomounconjuntodearchivosPHPquecontienenmatricesclave-valor.Entrelosarchivosmásusadosdeldirectorioconfigseencuentran:

app.php:Enestearchivonospuedeinteresarconfigurarellenguajedenuestraaplicación,lazonahoraria,losprovidersyaliasesdelasclasesmáscomunes.database.php:Enestearchivopodemosconfigurarprincipalmenteelmotordebasededatosalcuáldeseamosconectarnos.

Eldirectoriodatabase

Aquíseencontraranlosarchivosrelacionadosconelmanejodelabasededatos.Dentrodeestedirectorioseencuentranlossubdirectorios:

factories:Aquíescribiremosnuestrosmodelfactories.migrations:Todaslasmigracionesquecreamosseubicanenestesubdirectorio.seeds:Contienetodaslasclasesdetiposeed.

Capítulo4.EstructuradeunproyectoenLaravel

13

Page 14: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Eldirectoriopublic

Dentrodeestedirectoriocolocaremostodoslosrecursosestáticosdenuestraaplicación,esdecir,archivoscss,js,imágenesyfuentes.

Esrecomendablecrearunacarpetaporcadatipoderecurso.

Eldirectorioresources

Dentrodeestedirectorioseencuentranlossubdirectorios:

assets:Aquíseubicantodoslosarchivoslessdenuestraaplicación(útilparadesarrolladoresfront-end).lang:Aquíseencuentrantodoslosarchivosdeinternacionalización,esdecir,losarchivosparapoderpasarnuestroproyectodeunidiomaaotro.Normalmentehabráunacarpetaporcadaidioma,ejemplo:

en:idiomaingléses:idiomaespañol

views:Aquíubicaremosnuestrasvistasenformatophpophp.blade,esrecomendablecrearunacarpetaporcadacontrolador,ademásagregarunacarpetatemplatesparalasplantillas.Unaplantillaesunavistageneral,quetienesegmentosquepuedenserreemplazadosmediantelaherenciadeplantillas,másadelantesehablarádeestetema.

Eldirectoriostorage

CuandoLaravelnecesitaescribiralgoeneldisco,lohaceeneldirectoriostorage.Porestemotivo,tuservidorwebdebepoderescribirenestaubicación.Aquípodemosencontrarotrosdirectoriosentreloscualeselmásrelevanteeselsubdirectorioframework,esahí

Capítulo4.EstructuradeunproyectoenLaravel

14

Page 15: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

dondesealmacenaelcacheylasvistascompiladas.

Eldirectoriotests

Aquíescribiremoslosarchivosdepruebasqueseránejecutadasposteriormenteporphpunit.

Elarchivo.envy.env.example

Elarchivo.envnoexistecuandoinstalamoslaravel,enestearchivoseconfiguraráelmodoenqueseejecutanuestraaplicación,pordefectoseráelmododebug,ademáspodemosconfigurarlaconexiónalabasededatosylaconexiónconelservidordecorreoelectronico.Elarchivo.envlocreamoscopiandoelarchivo.env.exampleyrenombrandolacopiacomo.env.

Pormotivosdeseguridaddelabasededatoselarchivo.envnuncasesubecuandohacemosunpushennuestrorepositorio.Esporesoqueapareceescritodentrodelarchivo.gitignoreenlaraízdenuestroproyecto.

Capítulo4.EstructuradeunproyectoenLaravel

15

Page 16: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

JSONJSONesunacrónimodeJavaScriptObjectNotation,unformatoligerooriginalmenteconcebidoparaelintercambiodedatosenInternet.JSONnospermiterepresentarobjetos,arrays,cadenas,booleanosynúmeros.

LaventajadeusarJSONparalatransferenciadeinformaciónesquepuedeserparseadaporvarioslenguajesyesunformatoestandarizado,esdecirquecualquierlenguajepuedeintercambiardatosconotromedianteJSON.

Pordefecto,JSONseguardasinespaciosentresusvaloreslocuallopuedehacerunpocomásdifícildeleer.Estosehacenormalmenteparaahorraranchodebandaaltransferirlosdatos,sinlosespaciosenblancoadicionales,lacadenaJSONserámuchomáscortayportantohabrámenosbytesquetransferir.

Sinembargo,JSONnoseinmutaconlosespaciosenblancoosaltosdelineaentrelasclavesyvalores,asíquepodemoshacerusodeellosparahacerlounpocomáslegible.JSONesunformatodetransferenciadedatoynounlenguaje.

DebemostenersiempreencuentaqueenelformatoJSONlascadenassiemprevanencomillasdobles,además,loselementosclaveyvalordebesestarseparadascondospuntos(:),ylasparejasclave-valorporunacoma(,).

Porejemplo:

{

"Frutas":[

{

"Nombre":"Manzana",

"Cantidad":20,

"Precio":10.50,

"Podrida":false

},

{

"Nombre":"Pera",

"Cantidad":100,

"Precio":1.50,

"Podrida":true

}

]

}

LostiposdevaloresaceptadosporJSON

Capítulo5.JSON

16

Page 17: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

LostiposdevaloresquepodemosencontrarenJSONsonlossiguientes:

Numéricos(enterooflotante)Stringsocadenas(entrecomillasdobles)Booleans(trueofalse)Arraysoarreglos(entrecorchetes[])Objetos(entrellaves{})Null

¿PorquéaprenderJSON?

JSONesutilizadoampliamenteen:

Elarchivocomposer.jsondeproyectosPHPIntercambiodeinformaciónRepresentacióndeunabasededatosAJAXWebServices

ValidacióndeJSON

JSONesununformatoparaelintercambiodeinformaciónmuyrígidoyestricto,sitenemosunerrordesintaxis,obtendremosunerrorynopodremosparsearelJSON.Parasolucionarestetipodeproblemas,existeneninternetungrannúmerodeherramientasquenosayudanaescanearyencontrarposibleserroresenlaformacióndenuestroJSON.

PodemosocuparJSONLintqueesunamuybuenaopción,bastaráconcopiarypegarnuestroJSONeneláreadetextoyacontinuacióndarclickenelbotón"Validate".

JSONLintnosinformarásiescorrectoelformatooencasocontrarionosmostraráloserroressintácticosdenuestroJSON.

Capítulo5.JSON

17

Page 18: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

MigracionesCuandocreamosnuestrasbasesdedatossolemoscreardiagramasquenosfacilitanlaabstraccióndecomosevaaalmacenarnuestrainformación,perolaformadellevarloalarealidadenalgungestordebasesdedatos,comoporejemplo:MySQL,SQLite,PostgreSQL,SQLServer,etc.,lomáscomunesmeternosallenguajedescriptencargadodeimplementarnuestraideadelaBDyejecutardichoscript,oinclusoocuparprogramasmásavanzadosquenossirvencomointerfazparacrearlasdeunaformamásgráficaysinlanecesidaddeprofundizardemasiadoenellenguaje,comoWorkbenchoNavicat.

EnLaravelsellevaaotrocontextoestasituación,puestoquevistodelaformatradicionalsiserequierencambiosenlabasededatostenemosquemeternosyaseaaotroprogramaparacambiareldiagramadelabaseoaunarchivoSQLconunasintaxisusualmentecomplicadaodifícildeleeryejecutarloscambiosparareflejarlosenelproyecto,sinembargo,conestonocontamosconuncontroldeloscambios(controldeversiones)sobrelabasededatos,sinecesitamosconsultaruncambioanterioroderepentelasoluciónpreviaoinicialeralaquesenecesitaalmomentodebemosre-escribirtodootravez,cosaqueconlamigracionessesolucionainstantaneamente.

Lasmigracionessonarchivosqueseencuentranellarutadatabase/migrations/denuestroproyectoLaravel,pordefectoenlainstalacióndeLaravel5seencuentrandosmigracionesyacreadas,create_users_tableycreate_password_resets_table.

ParacrearnuestrasmigracionesenLaravelseusaelsiguientecomando:

phpartisanmake:migrationnombre_migracion

quenoscreaelarchivolimpioparaescribirnuestramigración,obienelcomando:

phpartisanmake:migrationnombre_migracion--create=nombre_tabla

quenosagregaunaplantilladetrabajobásicaparaempezaratrabajar.

Comoejemplodelcursosetomaráestecomando:

phpartisanmake:migrationcrear_tabla_pasteles--create=pasteles

elcualnosdaráesteresultado:

Capítulo6.MigracionesySeeders

18

Page 19: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

CreatedMigration:2015_06_23_054801_crear_tabla_pasteles

Ynoscrearáademáselsiguientearchivo:

Ahorabiensepuedeobservarqueelarchivocomotalnosellamasimplementecrear_tabla_pastelessino2015_06_23_054801_crear_tabla_pasteles,estopasaporqueLaravelalcrearunamigraciónagregacomopréfijolafechayhoraenlaquefuécreadalamigraciónparapoderordenarquémigraciónvaantesqueotra,porlocualsituejecutasestecomando,obviamenteelnombredetuarchivoserádiferentepueslafechayhoranopuedenserlasmismasquelamiaalcrearesteejemplo.AdemáslasmigracionesquevienenpordefectoenLaraveltambiénseencuentranconesteformatoporlocualpodemosobservarqueestosdosarchivossitienenelmismonombre.

Dentrodelaestructuradelarchivopodemosverdosfunciones,unallamadaup()yotrallamadadown(),laprimerfunciónesendondevamosaespecificarlaestructuradenuestratabla,inicialmenteygraciasalcomandoseencuentranyaalgunascosasescritascomolosonlaclaseSchemaenlacualsellamaalmétodocreate,elcualnospermitecrearlatabla

Capítulo6.MigracionesySeeders

19

Page 20: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

ennuestrabasededatos,estarecibedosparámetros,elprimeroeselnombrequevaarecibirlatablaquesinomalrecuerdaneselqueseledioenelcomandoyporlocualyaseencuentraensulugar,yelsegundoparámetroesunafunciónclosureofunciónanónimaqueloquehaceesdefinirlascolumnasdenuestratabla,asuvezestafunciónanónimarecibecomoparámetrounobjetodetipoBlueprintqueseagregódentrodelnamespaceconlapalabrauseenlacabeceradelarchivo,elobjeto$tableesconelquevamosatrabajarparadefinirloscampos,comoseveenlaimagenanteriorestoselograescribiendo$table->tipo_dato('nombre');,yestopuedevariardependiendoeltipodedatoqueseuseyparaellopodemosrevisarladocumentaciónoficialdeLaravelaquíparapodervertodoslostiposdecamposconlosquecontamos.

Enelejemploobservamosqueyatenemoselcampo'id'detipoincrementsqueesequivalenteauncampoenSQLasí:

createtablepasteles(idintauto_increment);

Yuncampodetipotimestampssinnombre,elefectoquetendráseráagregardoscolumnasmuyútilesquesoncreated_atyupdated_atquesoncamposqueseusanpara(comosunombrelodice)guardarelregistrodecuandofuecreadoycuandofueactualizadoelregistro,detallesmuyimportantescuandoqueremosobtenerinformesconbaseeneltiempodelainformacióndenuestratabla,porejemplosiquisieramossabercualessonlospastelesquesedierondealtaenelcatálogoenelmesdeabrilpodriamoscrearunfiltroparaobtenersololospastelesdeesemesusandoelcampogeneradocreated_at.

Ahorabiensilafunciónupcreanuestratablaenlabasededatos,lafuncióndownlogicamentehaceloopuesto,yesoeseliminarlatabladelabasededatos,poresodentrodeestafunciónpodemosobservarquedelamismaclaseSchemasellamaalmétododropquesignificadejarcaerodardebaja.

Sibiencadafunciónrealizaunatareaenespecifico,¿Cuandoesqueseusan?o¿Comosemandanallamar?.Buenoparaestoiremosnuevamenteanuestralineadecomandos.

Paracorreroiniciarnuestrasmigracionesusamoselcomando:

phpartisanmigrate

Conestosieslaprimeravezqueseejecutaestecomandosecrearáennuestrabasededatoslatablamigrationsqueeslaencargadadellevarelcontroldequemigracionesqueyahansidoejecutadas,conelfindenocorrerelmismoarchivomásdeunavezsielcomandoseusanuevamente.

Capítulo6.MigracionesySeeders

20

Page 21: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Entoncessicreamosnuestramigracióncrear_tabla_pastelesyusamoselcomandophpartisanmigratecomoresultadoennuestrabasededatosseagregarálatablapastelesyenlatablamigrationsseañadiráelregistrodelamigraciónrecienejecutada.

Pero,¿siquisieraeliminarlatablaconlafuncióndowndelamigracióncrear_tabla_pasteles?

Estosepuederesolverdedosformasbásicamente:

1. Conelcomandophpartisanmigrate:rollbackqueloqueharáesdeshacerlaúltimamigraciónejecutadayregistradaenlabasededatos.

2. Conelcomandophpartisanmigrate:resetqueloqueharáesdeshacertodaslasmigracionesdelabasededatos.

Nota:Uncomandoextraquenospermiteactualizarlasmigracioneseselcomandophpartisanmigrate:refresh,elcualesequivalenteausarphpartisanmigrate:resetydespuésphpartisanmigrate.

Eneldadocasoquenecesitaramosagregarmáscamposalatablapasteles,podríamossimplementeiralamigracióncrear_tabla_pastelesyenlafunciónupponerlanuevacolumna,peroconestoperderiamoslaprimerversióndelatabla,entoncesparapoderejeplificarcomoseagregancolumnasconlasmigracionescrearemosunanuevaquesellameagregar_campos_tabla_pastelesconloscomandosqueyahemosvisto:

1. Primeroejecutamoselcomando:phpartisanmake:migrationagregar_campos_tabla_pasteles,paracrearlamigraciónsimplesinlaplantilla.

2. Dentrodelafunciónupagregamosloscamposquenecesitamos,enestecasosoloagregaremoselnombreyelsabor.

3. Despuéscomolafuncióndownhaceloopuestoquelafunciónup,dentrodeestaeliminaremosloscamposrecienagregados.

Ahoraelarchivoresultantequedaríaasí:

Capítulo6.MigracionesySeeders

21

Page 22: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

ParapoderagregarmáscolumnasalastablasdesdeLaravelenvezdellamaralmétodocreatellamamosalmétodotabledelaclaseSchemapasandolecomoprimerparámetroaquetablasevaaagregarloscamposycomosegundoparámetrolafunciónanónimadondedefinimosquecolumnasseagregaran.

Yenlafuncióndownparaeliminarcolumnasquevendríasiendoloopuestodeagregarlas,sellamaalmétodotableydentrodelafunciónanónimadelobjeto$tableseusaelmétododropColumn()querecibecomoparámetroyaseaelnombredeunasolacolumnaounarreglocontodaslascolumnasquesedeseaneliminar.

Y¡listo!,conestopodemostenerunaideainicialdecomousarlasmigraciones,loqueparaesteejemplopodríacontinuarseríaagregarmáscolumnasalatablapastelesyprobarloscomandosnecesariosparapoderdeshacerloscambiosdelaprimeravezquesecorriolamigraciónconunanuevaversión,yaseasobreelmismoarchivoosobreotronuevo.

Beneficios

Tenemosunmayorcontroldelasversionesdelabasededatos.

Capítulo6.MigracionesySeeders

22

Page 23: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Podemosconunsimplecomandoverreflejadosloscambiosdenuestrabasededatos.

EllenguajeenelcualsetrabajasiguesiendoPHP,porlocualnosediferenciatantodeloqueyanosacostumbraremosconLaravel.

LaultimaversióndenuestrabasesiempreestaráactualizadaparatodoslosmiembrosdelequipodetrabajosiusamosuncontroldeversionescomoGIT.

Proveedeportabilidadparadiferentesgestores,usandoelmismocódigo.

SeedersLosSeedersporotrapartesonarchivosquenosvanapermitirpoblarnuestrabasededatosparanotenerqueperdereltiempoescribiendodeformamanualtodoslosdatos,unejemplo,imaginallenar15tablascon100registroscadaunaypiensaenqueentrecadatabladebenexistirregistrosqueserelacionanentresí,esosuenadeverdadhorribleytedioso,porlocualLaravelnossalvaconestosarchivosSeeders.

UnSeederseubicaenlacarpetadatabase/seeds/denuestroproyectodeLaravelyparapodercrearunnuevoSeederseusaelcomando:

phpartisanmake:seedernombre_seeder

Estonoscrearáunarchivoenlacarpetadatabase/seeds/quetendráelnombrequeledemosenelcomando,porejemplocrearemosunoretomandoelejemploanteriordelasmigraciones,sellamaráPastelesSeeder,porlocualelcomandoquedariadelasiguienteforma:

phpartisanmake:seederPastelesSeeder

Conestoyatenemoselarchivoperonoestodoloquenecesitamosparapodertrabajarcondatosautogenerados,paraellousaremosuncomponentellamadoFakerelcualseencargarádegenerarestosdatos,pordefectoelboilerplatedelproyectodeLaravel5.1queestamostrabajandovieneyaconFakerdentrodelcomposer.jsonporlocualyadebeestarinstaladodentrodenuestroproyecto,ahorabiensiestamostrabajandoconunainstalaciónLaravel5.0sinelcomponenteFakerbastaconiralarchivocomposer.jsonyagregarenel"require-dev"lasdependenciasyparatenerunaideamásclarapodemosiralapáginadePackagistdondeseencuetraFakeroasuRepositorioenGithubyahínosmuestraqueesloquesedebeagregar.

Capítulo6.MigracionesySeeders

23

Page 24: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

AlfinalsoloseocupaelcomandocomposerupdateparaactualizarlasdependenciasydescargarFakeralproyecto.

UnavezyateniendoFakeriremosanuestroarchivoPastelesSeederydentropodremosobserverqueseencuentraunafunciónllamadarun()queesdondenosotrosvamosausarFakerparapoblar,ahorabienantesdetododebemosagregarlaclasedeFakeranuestroSeeder,paraestoagregamosaliniciodelarchivolalinea:

useFaker\FactoryasFaker;

Quedandoelarchivodelasiguienteforma:

Despuéscrearemosunavariablellamada$fakerquenosserviraparapoblarlabasededatos,ahorabienusandolaclaseDB,sibiendentrodelejemploqueremoscrear50pastelesvamosacrearunforparaqueejecutenuestrocódigodeinserción50vecesyelcomponentedeFakerencadapasadacambiarálosvaloresdelregistroquesevaaagregar,quedandodeestaforma:

$faker=Faker::create();

for($i=0;$i<50;$i++){

\DB::table('pasteles')->insert(array(

'nombre'=>$faker->firstNameFemale,

'sabor'=>$faker->randomElement(['chocolate','vainilla','cheesecake']),

'created_at'=>date('Y-m-dH:m:s'),

'updated_at'=>date('Y-m-dH:m:s')

));

}

Capítulo6.MigracionesySeeders

24

Page 25: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

CreamosnuestroobjetoFaker,elcualpuedegenerarinformaciónfalsaparanuestrabasededatosyahorausamoslaclaseDBelmétodotableparallamarlatabladondesevaainsertarlainformaciónyseleconcatenaelmétodoinsert()elcualrecibeporparametrounarregloclave=>valorconloscamposdelatabla.

Fakertienemuchasvariedadesdedatos,loscualespodemosconsultarensuRepositoriodeGithubasícomosuusobásico.

EnesteejemplousamosunapropiedadquesellamafirstNameFemaleparadarlenombrealpastelylapropiedadrandomElementquedeunarregloqueseledaasignaunelementodeesearregloaleatoriamente.

YahoraloquesigueesabrirunarchivollamadoDatabaseSeeder.php,enestearchivosemandanallamartodoslosseedersenelordenquelosnecesitemos,enestearchivoseagregarálalinea:

$this->call('PastelesSeeder');

queensimandaráallamarnuestroseederreciencreadoyparaejecutarestearchivoseusaelcomando:

phpartisandb:seed

Yconestoquedapobladalatablapastelesylopuedesverificarentugestordebasededatos.

CuandotrabajamosconMigracionesySeederporprimeravezpuedeparecerunpocomáscomplicadoquealoqueestamosacostumbradosperolasventajasquenosdasuperanpormuchoalaformaconvencional,ademásdeserunaformamásprofesionaldetrabajar.

Unoscomandosextrasquenospuedenserutilesson:

phpartisanmigrate--seed

Elcomandoanteriorloquehaceesrealizarunacombinaciónentreloscomandosphpartisanmigrateyphpartisandb:seed.

phpartisanmigrate:refresh--seed

Elcomandoanteriorloquehaceesrealizarunacombinaciónentreloscomandosphpartisanmigrate:refreshyphpartisandb:seed.

Capítulo6.MigracionesySeeders

25

Page 26: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Capítulo6.MigracionesySeeders

26

Page 27: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

ModelosyusodeEloquent

Eloquent

EnLaravelpodemoshacerusodeunORMllamadoEloquent,unORMesunMapeoObjeto-Relacionalporsussiglaseningles(Object-Relationalmapping),queesunaformademapearlosdatosqueseencuentranenlabasededatosalmacenadosenunlenguajedescriptSQLaobjetosdePHPyviceversa,estosurgeconlaideadeteneruncodigoportableconelquenotengamoslanecesidaddeusarlenguajeSQLdentrodenuetrasclasesdePHP.

EloquenthaceusodelosModelospararecibiroenviarlainformaciónalabasededatos,paraestoanalizaremoselmodeloquevienepordefectoenLaravel,esteeselmodeloUserqueseubicaenlacarpetaapp/,losmodeloshacenusodePSR-4ynamespaces,unmodelonosayudaadefinirquetabla,atributossepuedenllenaryqueotrossedebenmantenerocultos.

LosmodelosusanconvencionesparaqueaLaravelselefaciliteeltrabajoynosahorretantolíneasdecódigocomotiempopararelacionarmásmodelos,lascualesson:

Elnombredelosmodelosseescribeensingular,encontrasteconlastablasdelaBDqueseescribenenplural.

UsannotacionUpperCamelCaseparasusnombres.

Estasconvencionesnosayudanadetectarautomaticamentelastablas,porejemplo:elmodeloUserseencuentraensingularyconnotacionUpperCamelCaseyparaLaravelpoderdefinirquetablaeslaqueestaligadaaestemodeloleessuficienteconrealizarlaconversionanotacionunderscoreyplural,dandocomoresultadolatabla:users.

Yestoaplicaparacuandoqueremoscrearnuestrosmodelos,sitenemosunatablaenlabasededatosconlaquequeremostrabajarquesellamauser_profiles,vemosqueseencuentraconlasconvencionesparatablasdebasesdedatos(pluralyunderscore),entonceselmodeloparaestatablacambiandolasconvencionesseria:UserProfile(singularyUpperCamelCase).

RetomandoelejemploquevimosenelCapítulo6sobrelamigraciondepasteles,crearemosahoraunmodeloparapodertrabajarconesatabla,elcualrecibiraelnombredePastelyelcomandoparapodercrearnuestromodeloses:

phpartisanmake:modelPastel

Capítulo7.ModelosyusodeEloquent

27

Page 28: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

ConestosegeneraraelarchivoendondeyaseencuentraelmodeloUserenlacarpetaapp/ydentrodeelvamosadefinirlatablaquesevaausarconestalinea:

protected$table='pasteles';

¿PeronosesuponiaqueLaravelidentificabaautomáticamentequetablausar?

SilohaceperosicambiamoslasconvencionesdelmodeloPastelelresultadoseriapastelsynuestratablasellamapasteles,estoesunproblemaparanosotrosporelhechodelusodellenguajeespañolporquelaconversiondesingularapluralnoeslamismaquelaformaenquesehaceeningles,debidoaestonosvemosforzadosadefinirelnombredelatabla.

Bienunavezcreadonuestromodelopasaremosacrearunarutadetipogetennuestroarchivoroutes.php,posteriormenteestudiaremoselenrutamientobásicoenLaravelenelCapítulo9,porelmomentosoloseguiremoselejemplo,quequedariadelasiguienteforma:

Route::get('pruebasPastel',function(){

});

Dentrodeestarutadepruebavamosausarnuestromodelo,perocomoestamosusandolaespecificacionPSR-4debemosincluirelnamespacedelmodeloaliniciodelarchivo,queseriaigualaesto:

useCurso\Pastel;

ConestoestamosdiciendoqueincluyalaclasePastelqueesnuestromodelo,yconestopodemosyahacerconsultasanuestraBDymapearaobjetosPHP.EnladocumentacionoficialdeLaravelpodemosvertodaslasopcionesquenospermiteEloquent,unasdelasinstruccionesbasicasdeestesonget()quenosregresatodoslosregistrosdelaBDyfirst()quenosregresaelprimerregistrodeunaseleccion.

AsuvezpodemosunirestoamásfiltrosdeseleccionSQL,comoporejemploseleccionarelprimerpasteldevainilla,lasintaxisdeEloquentserialasiguiente:

$pastel=Pastel::where('sabor','vainilla')->first();

Estonosvaadarelprimerpastelsaborvainilla,perosiquisieramostodoslospastelesdevainillacambiariamoselmetodofirst()porelmetodoget()paraobtenertodos.

Capítulo7.ModelosyusodeEloquent

28

Page 29: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Ysiqueremosverelresultadodeestoyquedeverdadestamoshaciendolocorrectopodemosusarlafunciondd()paramostrarenpantallaelvalordeunavariable,conestoentoncesnuestrarutaleagregariamoslosiguiente:

Route::get('pruebasPastel',function(){

$pasteles=Pastel::where('sabor','vainilla')->get();

dd($pasteles);

});

Yenelnavegadordeberiamosveralgocomoesto:

Estoeslafuncióndd($pasteles)mostrandoelcontenidodelavariable$pasteles.Ahorabiensituvieramoslanecesidadderealizarsiempreunmismofiltro,Eloquentnosproveedeunaherramientallamadascopesqueloquerealizansonconsultasenespecificoencapsulandolasdentrodefuncionesenelmodelo,porejemplosiquisieramosqueelmodeloPasteltuvieraunafuncionquemedieratodoslospastelesdevainilla,otradechocolateyotrafunciónmasparacheesecake,entoncespodriacrearunscopeparacadauna.

ConelejemplodelarutapruebasPastelparaelsaborvainilla:

publicfunctionscopeVainilla($query){

return$query->where('sabor','vainilla');

}

Capítulo7.ModelosyusodeEloquent

29

Page 30: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

LosscopesenlafunciónsedebeiniciarelnombredelafunciónconlapalabrascopeyseguidoennotacioncamelCaseelnombreconelcualsevaallamarelscope.Ysuequivalentedentrodelarutaserialasiguiente:

Route::get('pruebasPastel',function(){

$pasteles=Pastel::vainilla()->get();

dd($pasteles);

});

Tambiénpodemoscrearscopesdinámicosdelasiguienteforma:

publicfunctionscopeSabor($query,$sabor){

return$query->where('sabor',$sabor);

}

Estonosdariaunafuncióngenéricaparaobtenerlospastelesdeciertosaborysuimplementaciónseríaasi:

Route::get('pruebasPastel',function(){

$pasteles=Pastel::sabor('vainilla')->get();

dd($pasteles);

});

AdemásconEloquenttambienpodemosinsertar,actualizaroeliminarregistros,porejemplo:

Parainsertarlasintaxisserialasiguiente:

$pastel=newPastel;

$pastel->nombre='PastelRichosStyle';

$pastel->sabor='chessecake';

$pastel->save();

Paraactualizarserialasiguiente:

$pastel=Pastel::find(51);

$pastel->sabor='chocolate';

$pastel->save();

Paraeliminarserialasiguiente:

Capítulo7.ModelosyusodeEloquent

30

Page 31: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

$pastel=Pastel::find(51);

$pastel->delete();

obienpodriamosdestruirelregistrodirectamenteconelmodelositenemossuID:

Pastel::destroy(51);

Capítulo7.ModelosyusodeEloquent

31

Page 32: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

ModelFactoriesLosmodelfactoriessonunaexcelenteformadepoblarnuestrabasededatoscondatosdepruebageneradosautomáticamente.Laravelensuversión5.1incorporaestenuevocomponentepordefecto,enversionesanterioresaLaravel5.1eranecesarioagregarelcomponentefakerennuestrocomposer.jsonyrealizarelprocesodemaneramanualenlosarchivosseeders,paramásinformaciónsobreestreprocesopuedesvisitarellinkdegithubdelcomponenteFaker.

LosmodelFactoriesenrealidadtambiéntrabajanconelcomponenteFaker,estolopodemosconfirmarsimiramosnuestrocomposer.json,sinembargo,nosofrecenunamaneramáseleganteyordenadadetrabajar.

Laravel5.1traeunejemplodecomousarestenuevocomponente,lopodemosencontrarenelarchivodatabase/factories/ModelFactory.php.

Elmétodo$factory->define()regresaunarrayconlosdatosdelmodeloquesevaapoblar,recibecomoprimerparámetroelmodeloconelquedeseamostrabajarycomosegundoparámetrounafunciónquerecibecomoparámetrounobjeto$faker.

Ejemplo:

$factory->define(App\User::class,function($faker){

return[

'name'=>$faker->name,

'email'=>$faker->email,

'password'=>str_random(10),

'remember_token'=>str_random(10),

];

});

Elmétodo$factory->defineAs()regresaunarrayconlosdatosdelmodeloquesevaapoblar,recibecomoprimerparámetroelmodeloconelquedeseamostrabajar,comosegundoparámetrountipoespecificodepobladoycomotercerparámetrounafunciónquerecibecomoparámetrounobjeto$faker.

Ejemplo:

Capítulo8.Modelfactories(Poblarbasededatosconfaker)

32

Page 33: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

//Creamosunmodelfactoryparapoblarusuariosdetipoadministrador

$factory->defineAs(App\User::class,'administrador',function($faker){

return[

'name'=>$faker->name,

'email'=>$faker->email,

'password'=>str_random(10),

'type'=>'administrador',

'remember_token'=>str_random(10),

];

});

//Creamosunmodelfactoryparapoblarusuariosdetipoencargado

$factory->defineAs(App\User::class,'encargado',function($faker){

return[

'name'=>$faker->name,

'email'=>$faker->email,

'password'=>str_random(10),

'type'=>'encargado',

'remember_token'=>str_random(10),

];

});

EnelejemplodearribahemoscreadodostiposdepobladoparaelmodeloUser,unoseráparapoblarusuariosdetipo"administrador"yotroparausuariosdetipo"encargado".

UnavezcreadoslosModelFactories,debemosiralarchivodatabase/seeds/DatabaseSeeder.phpyejecutarelpobladodentrodelmétodoruncomoenelsiguienteejemplo:

publicfunctionrun()

{

Model::unguard();

factory('Curso\User',50)->create();

factory('Curso\User','administrador',1)->create();

//$this->call('UserTableSeeder');

Model::reguard();

}

Elobjetofactoryrecibecomoparámetroselnombredelmodelo,eltipodepobladocomoparámetroopcionalyelnúmeroderegistrosquedeseamoscrear.Conelmétodocreaterealizamoselpobladodedatos.

Ejemplos:

Capítulo8.Modelfactories(Poblarbasededatosconfaker)

33

Page 34: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

factory('Curso\User',100)->create();

//Opcionalmentepodemosagregareltipodepoblado

factory('Curso\User','administrador',100)->create();

Capítulo8.Modelfactories(Poblarbasededatosconfaker)

34

Page 35: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

EnrutamientobásicoLasiguienteimágenmuestraelprocesoqueserealizacuandoingresamosaunaURL.AdemásmuestralaarquitecturadelpatrónMVCqueutilizalaravelparaeldesarrollodeproyectos.

CuandoingresamosaunaurldirectamentedesdeelnavegadorlohacemosmedianteunapeticiónhttpdetipoGET,estasolicitudseenvíaalarchivoroutes.phpubicadodentrodeapp/Http/routes.php,encasodenoexistirnosdaráunerror,silarutaexiste,nosllevaráauncontroladorenelcuálseencuentralalógica,elcontroladorinteraccionaráconunmodelo(opcionalmente)pararecuperarinformacióndeunabasededatos.Estainformaciónllegaalcontroladorydesdeelcontroladorinvocamosunavista,lasvistasseencuentraneneldirectorioresources/views,finalmentelavistasecargaysemuestraenelnavegador.

AsíescomofuncionaelmodeloMVC(Model-View-Controller).

SupongamosquequeremosingresaralasiguienteURLhttp:/dominio.com/saludoydesplegarunapáginaconelmensaje“Bienvenido:)”.Enlaravellaporción/saludoperteneceríaaunarutaqueregresaunarespuestaounavistadependiendolocomplejoquellegueaserloquequeramosmostrar.Lapartededominio.comperteneceríaalocalhost

Capítulo9.Enrutamientobásico

35

Page 36: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

siloandamosprobandodemaneralocal.Ennuestroejemploloquemostraremosesunmensajemuysimpleporlocualnoesnecesariohacermostrarunavista.Paralograrloharemoslosiguiente:

Route::get('saludo',function(){

return"Bienvenido:)";

});

Loquedeberíamostrarunmensajesimilaraeste:

TiposderutasporencabezadoHttp

LasrutasestánsiempredeclaradasusandolaclaseRoute.Esoesloquetenemosalprincipio,antesde::.Lapartegeteselmétodoqueusamospara‘capturar’laspeticionesquesonrealizadasusandoelverbo‘GET’deHTTPhaciaunaURLconcreta.

Comoverás,todaslaspeticionesrealizadasporunnavegadorwebcontienenunverbo.Lamayoríadelasveces,elverboseráGET,queesusadoparasolicitarunapáginaweb.SeenvíaunapeticiónGETcadavezqueescribesunanuevadirecciónwebentunavegador.

Aunquenoeslaúnicapetición.TambiénestáPOST,queesusadaparahacerunapeticiónyofreceralgunosdatos.NormalmenteseusaparaenviarunformularioenlaquesenecesitaenviarlosdatossinmostrarloenlaURL.

HayotrosverbosHTTPdisponibles.Heaquíalgunosdelosmétodosquelaclasedeenrutadotienedisponibleparati:

Route::get();

Route::post();

Route::any();

Route::delete();

Route::put();

CualquiermétododelaclaseRouterecibesiempredosargumentos,elprimeroeslaURIconlaquequeremoshacercoincidirlaURLyelsegundoeslafunciónarealizarqueenestecasoesunClousurequenoesotracosaqueunafunciónanonima,esdecir,quenotieneunnombre.

Rutasdetipoget

Capítulo9.Enrutamientobásico

36

Page 37: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Enestecasoocuparemoselmétodoestáticogetparaescribirunarutaquerespondaaunapeticióndeestetipo,lasrutasdetipogetsonlasmásusadas.Elmétodoestáticogetrecibecomoprimerparámetrounstringindicandolaurlconlacuálvamosaingresar,elstring"/alumnos"responderáalasolicitudhttp://localhost:8000/alumnos,elstring"/"equivaleahtpp://localhost:8000,esdecir,larutapordefecto.Comosegundoparámetroelmétodoestáticogetrecibeunclosure(unafunciónsinnombre)quepuededevolverunaviewounstring.

//rutadetipoGETquedevuelveunavista

Route::get('/',function(){

returnview('welcome');

});

//rutadetipoGETquedevuelveunsimplestring

Route::get('/',function(){

return"Holamundo";

});

Elmétodoviewdentrodelclosurerecibecomoparámetroelnombredeunavistasinlaextensión.Enelejemplodearribalavistawelcomeseencuentraubicadaenresources/views/welcome.blade.phpsiescribimosview('pasteles.lista_pasteles')estamosindicandoqueregresaráelarchivolista_pasteles.blade.phpubicadoenresources/views/pasteles/lista_pasteles.blade.php.Lasvistaslasveremosenelcapítulo10.

Lasrutaspuedenserrelacionadasconmétodosdeuncontrolador.Enelsiguienteejemplo,larutahttp://localhost:8000/homeregresaráloqueindiquemosenelmétodoindexdelControllerHomeController.

Route::get('home','HomeController@index');

Parametrosenlasrutasdetipoget

Losparámetrosdelasrutaspuedenserutilizadosparaintroducirvaloresderellenoentusdefinicionesderuta.EstocrearáunpatrónsobreelcualpodamosrecogersegmentosdelaURIypasarlosalgestordelalógicadelaaplicación.Paradejarlounpocomásclaropondremosunosejemplos.

Capítulo9.Enrutamientobásico

37

Page 38: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Deigualformaesposiblerestringirrutaspormediodeexpresionesregularescomoporejemplo:

Enlaimagenanteriorpodemosverdosconceptosnuevos,elusodevalorespordefaultlocúallogramosconelsimbolo(?)despuesdelnombredelavariableyenlafunciónasignandoleunvalorpordefecto,enestecasoelentero1.

LosegundoquevemoseselusodelmétodowhereelcúalnospermiteestablecerexpresionesregularesalasvariablesqueusamosenlaconstruccióndelasURIs.

Capítulo9.Enrutamientobásico

38

Page 39: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

VistasyBladeLasvistasenLaravelsonlapartepúblicaqueelusuariodenuestrosistemavaapoderver,seescribenenHTMLjuntoconunmotordeplantillasllamadoBlade.Lasvistasseencuentranubicadasenlacarpetaresources/views/yLaravelpordefectotrabajaconlaideadequetenemosqueescribirlamenorcantidaddecódigorepetido,modularizarnuestrocódigoendondemassepueda,ysiestoloaplicamosennuestrosmodelos,controladoresydemáspartesdenuestroproyecto,entonces,¿Porquenohacerlotambienenlasvistas?.

Laravelusaunosarchivosquesellamanplantillasotemplatesquesuelensernuestrosarchivosprincipales,quetienenlossegmentosdecódigoqueserepitenenmasdeunavista,comoporejemplolabarradenavegacion,unmenúdeopciones,laestructuradelacomododenuestroproyecto,etc.ycomodebendeestarpracticamentepresentesentodoslados,notienesentidoestarlosrepitiendoentodaslasvistas.PordefectoLaravelcontieneuntemplatellamadoapp.blade.php,usualmentelostemplatescontienenelheaddelHTML,lasligasdelCSSdelsistemayunaseccionexclusivaparalosarchivosJavascript.

Ademásdelostemplates,secuentanconarchivosquesellamanpartials,estosarchivossonpequeñossegmentosdecódigoquesuelenserusadoscomunmenteenpartesdelsistemaenespecifico,comolosformulariososeccionesdemensajes,estosarchivossurgenporelcódigoqueesmaspequeñoquerepetimosmuchoperonoeslosuficientementegrandecomoparaconsiderarlountemplate.

Estohacequelasvistasdecadapartedelproyecto,quesuelenserllamadasporunarutaocontroladorseanmuchomaspequeñasqueusandootrotipodeframeworksparadesarrolloWeb,yparapoderunirtodosestosarchivosopiezasdelrompecabezasusamoselmotordeplantillasdeLaravelllamadoBLADE.

AntesdevermassobreelmotordeplantillasBlade,veremoscomotrabajarconlasVistasyllamarlasdesdeunaruta,crearemosunvistasimpleconunarchivonuevoenlacarpetaresources/views/llamadosaludo.blade.phpconelsiguientecódigo:

Capítulo10.VistasymotordeplantillasBlade

39

Page 40: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<!DOCTYPEhtml>

<html>

<head>

<metacharset="utf-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<title>Vistaejemplo</title>

</head>

<body>

<h1>HolamundodesdeLaravel</h1>

</body>

</html>

EsunHTMLsimpleconuntitulo1,ahoravamosacrearunarutaquenosmuestreestavista:

Route::get('saludo',function(){

returnview('saludo');

});

Deestaformaconlafunciónview()leestamosdiciendoaLaravelquebusquedentrodelacarpetaresources/views/lavistasaludo.blade.php,porconvensionlasvistasLaravelnonecesitaqueespecifiquemoslaextension.blade.php,sinosolosunombre.Unavezhechoestodebemosveresteresultadoounosimilar:

ContinuandoconelejemplodelosPastelesvamosamandaralavistaelnombredeunpastel,dentrodelarutasaludovamosaobtenerelprimerPasteldechocolatedenuestraBDyaponeresenombreenvezdelmensaje.Paraestopodemosusarelscopedesabor

Capítulo10.VistasymotordeplantillasBlade

40

Page 41: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

paraobtenerlospastelesdechocolateydespuesdecirlequeconelmetodofirst()nosregreseelprimerpastelyesoguardarloenunavariable,dejandolarutadelasiguienteforma:

Route::get('saludo',function(){

$pastel=Pastel::sabor('chocolate')->first();

returnview('saludo')->with('pastel',$pastel->nombre);

});

Deestaformaestamosdiciendoalarutaquenosregreselavistasaludo.blade.phpconunavariablellamadapastel,queeselnombredelpastel,peroestoporsisolonolovaamostrarelnavegador,solovaamandarlavariable,paraqueelnavegadorlamuestredebemosagregaruntitulodondeesteesavariabledeestaforma:

<h2>{{$pastel}}</h2>

EstalineavajustoabajodelmensajeHolamundodesdeLaravel,yahorasidebemosdeveralgoparecidoaestoyaquenuestrasBDtienencosasdiferentesygraciasaFakerningunodenuestrosresultadosdeberiaserigual:

Ahorasibienusamosloscaracteresdelasdoblesllavesynosabemosbienqueson,estoespartedelasintaxisqueahoraveremosconBlade.

Blade

Capítulo10.VistasymotordeplantillasBlade

41

Page 42: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Bladenosproveedemuchasventajas(asicomocasitodoenLaravel),ademásdemodularizarnuestrasvistasdeunaformasorprendente,tambiennospermiteusarestructurasdecontrolyvariablesdePHPdirectamenteenellas,aunqueestoyaeraposibleantesusandolasetiquetasdephp,porejemplo:

<?phpecho$var?>

<?=$var?>

Peroestoademásdeserunpocoincomododeescribirdejanuestrasvistasmuchomásdifícilesdeentenderysuciasporlamezcladetantocódigo.

Entoncesparaelejemploanteriorusamoselsiguientecódigo:

{{$pastel}}

Estoeselequivalentea<?=$pastel?>yaunqueconunejemplotansencillonosevedemasiadadiferencia,conlosiguientepodremosverificarlapotenciadeestemotordeplantillas.

UsualmentelasestructurasdecontrolqueconocemoslasusamosenlosarchivosPHPdedicadosalBack-end(ladodelservidor),perobladenosdaunasintaxismuycomodaparaestetipodeestructurasqueconPHPplanosonmuysuciaseincomodasdeusar.

ParacadaunadeestasestructurascomolosonIf,else,elseif,for,foreach,etc.,seanteponeun@parausarestasestructurasylisto!!esoensuficiente,peroadiferenciadecomoestamosacostumbradosdeencapsularungrupodesentenciasolineasdecódigoconllaves{},enbladedefinimoselfindeunaestructuraconun@endseguidodelnombredelaestructuraqueusamos,porejemplo:

<h1>Listadepasteles</h1>

@foreach($pastelesas$pastel)

<h2>{{$pastel->nombre}}</h2>

@endforeach

Entoncesenlarutadonderegresamossolounnombredeunpastel,podriamosregresartodoslospastelesyescribirunalistadetodolospastelesdeunciertosaboreimprimirlaenlavista.

Unejemploparaelifseria:

Capítulo10.VistasymotordeplantillasBlade

42

Page 43: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

@if($pasteles->count()>10)

<h1>HaymuchosPasteles</h1>

@endif

<h1>Listadepasteles</h1>

@foreach($pastelesas$pastel)

<h2>{{$pastel->nombre}}</h2>

@endforeach

Elifnosdice,sielnumerodepastelesquerecibimosesmayora10entoncesescribeeltituloHaymuchosPasteles.

Estoaplicaparatodaslasestructuras,sulógicaeslamismaperosolocambiaunpocosusintaxis,perohacequeelHTMLquedemaslimpioquesiincrustaramosPHPplanodentrodenuestravista.

TemplatesyPartialsAnteriormentehablabamosdetemplatesypartials,describiremosunpocodecomosetrabajaconestaestructurasdeBladeysusbeneficios:

Templates

EstosarchivoscomosemencionaalprincipiodelcapítulosonplantillasquenosahorranmuchocódigooleguajeHTML,yparausaruntemplateseusalasentencia:

@extends('template')

Claramentesetendriaquesustituirlapalabratemplatedentrodelasentenciaextendsporelnombredelavistaquevaafuncionarcomotemplateoplantilla.

Untemplateesunavistacomolasdemás,simplementequedentrodeellaseusanotrassentenciasquenosvaapermitirdefinirareasdelarchivoquesevanapodersustituirmasadelantedentrodeotravistasiesquelodeseamos.Paraestoseocupalasentencia:

@yield('nombre_seccion')

Paradeclararunaseccionquesevaarellenarenotrolugar:

@section('nombre_seccion')

Capítulo10.VistasymotordeplantillasBlade

43

Page 44: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

quefuncionadelamismaformaqueyield()conladiferenciaqueenlaseccionpuedesdefinirHTMLpordefectoencasodenodefinirlaseccionconunnuevoHTML.

Definiremosnuestravistareciencreadasaludo.blade.phpparaqueuseuntemplate,pordefectoLaraveltraeunoquesellamaapp.blade.php,eseeselqueusaremosparaesteejemplo.

Eltemplateapppordefectotienedefinidaunyieldllamadocontentquesignificacontenido,porlocuallalistadepastelesquetenemoslavamosaagregarenestaparteylavistaquedariadelasiguienteforma:

@extends('app')

@section('content')

<h1>Listadepasteles</h1><br>

@if($pasteles->count()>10)

<h2>HaymuchosPasteles</h2><br>

@endif

@foreach($pastelesas$pastel)

<h4>{{$pastel->nombre}}</h4>

@endforeach

@stop

AhoranuestravistayanotieneelencabezadoHTMLnormalnilasetiquetas<body>ni<html>,sinoqueestamosdiciendoquevamosaextenderdeltemplateappyqueelyieldcontentlovamosasustituirpornuestropropiocontenido,cabemencionarqueaunqueeneltemplateseusolasentenciayield('content'),almomentodesustituirlalavamosacambiarporsection('content'),porlocualentodaslasvistashijasdeltemplatesolosevaadefinirseccionesyelfindeesaseccionsevaadeclararconlaentencia@stop.

Ahoraelresultadoseriaalgoparecidoaesto:

Capítulo10.VistasymotordeplantillasBlade

44

Page 45: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Nospodemosdarcuentaquecambiaronmuchascosas,ahoratenemosunabarradenavegacionenlapartesuperiordelaventanayeldebugbarenlaparteinferior,ademásdequelatipografiahacambiado.EstoesporquedentrodeltemplateappseestanagregandohojasdeestiloCSS.

Partials

Continuaremosconlospartials,basicamenteeslomismoqueyahemosvistoperoconunasentenciamasquesellamainclude('nombre.partial'),lacualestaincluyendooincrustandounarchivodeHTML,podemoshacerunsimilconlosusedePSR-4olosimportdeJava,adiferenciadequeestoloinlcuyejustoenellugardondelodefinimos.

Vamosaverloconunejemplopractico.

Dentrolaactualvistasaludo.blade.php,vamosaquitartodoelHTMLBladequedefinimosparacrearestalistapequeñadepastelesylovamosaguardarennuevoarchivo,paraestovamosacrearunacarpetallamadapastelesydentrootracarpetallamadapartials,dondevamosaguardarlavistadenuestronuevopartial,quedandolarutadelasiguienteforma:resources/views/pasteles/partials/.

Ahivamosacrearunarchivollamadolista.blade.phpydentrodeestearchivovamosacortarelcódigodenuestravistasaludo,quedandoasi:

Capítulo10.VistasymotordeplantillasBlade

45

Page 46: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<h1>Listadepasteles</h1><br>

@if($pasteles->count()>10)

<h2>HaymuchosPasteles</h2><br>

@endif

<ul>

@foreach($pastelesas$pastel)

<li>{{$pastel->nombre}}</li>

@endforeach

</ul>

Ynuestravistasaludo.blade.phpquedariadeestaformaunavezqueyaincluyamosnuestropartial:

@extends('app')

@section('content')

@include('pasteles.partials.lista')

@stop

Sitodolohacemosbiennuestravistaenelnavegadordebeseguirviendosedelamismamanera,perosisedancuentaahoraseencuentramuchomasmodularnuestroHTML,silalistadePasteleslanecesitaramosenotravistaahorasolonecesitamoshacerun@include('pasteles.partials.lista')yconesoyatendremosnuestralistaagregadaencualquiervistadondelanecesitemos.

Resumen,AnotacioneseinformacionadicionalBladeesunmotordeplantillaspotentequenospermitemodularizaryestilizaraungrannivelnuestroHTML.

ComorecordatoriolistaremosalgunasdelassentenciasdeBladejuntoconsufuncion:

@extends('nombre_template'):Estasentencianosayudaadecirleaunavistacualvaasereltemplatequesevaausar.

@yield('nombre'):EstasentencianospermitedeclararunfuturosectiondenuestroHTMLquesedefiniraenlasvistasquesonheredadasynopuedeagregarsealguntipodecontenidopordefecto,estesóloseusaenarchivosquetomanelroldeTemplate.

@section('nombre'):Estasentenciatienedosusosdependiendodequequeremosdeclarar,elprimeroesquenospermitedeclararcomosunombrelodiceunaseccióndentrodeltemplatequepuedeteneruncontenidopordefectoquesinoesredefinidoenlavistaqueheredeeltemplateentoncesaparecera;elsegundonospermiteasignar

Capítulo10.VistasymotordeplantillasBlade

46

Page 47: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

elcontenidoenunaseccionquefuedeclaradaennuestrotemplate,esdecirestapalabrasectionseusatantoeneltemplatecomoenlasvistashijas,unadiferenciamasesquesiseusaeneltemplateentonceslaseccionteminaconun@show,perosiseusaenunavistahijaentoncesterminalaseccionconun@stop.

@show:Estasentenciaseusaparadecirdondeterminaelsectiondefinidoeneltemplate.

@parent:Estasentencianosayudaacargarelcontenidopordefectodeunsectiondeltemplate,estopodemosusarlocuandoqueremosagregarmascontenidodentroperosinalterarelcontenidopordefecto,esdeciragregarlemasHTML,estasentenciaseusadentrodeunsection,podemoshacerunsimilconelsuper()deJavaquesirveparallamaralcontructordelasuperclasedelaquesehereda.

@stop:Estasentencianospermitedecirdondeterminaunsectioncuandoseusaelsectiondentrodelasvistashijas.

@include('ruta.nombre'):Estasentencianosagregaenellugardondeseausadaunarchivoblade.phpquecontieneunpartialofragmentoparcialdeHTML,siesepartialseencuentraenlaraízdelasvistasnonecesitamasqueelnombresinlaextensionblade.php,perosiestadentrode,porejemplo,lacarpeta"views/admin/users/"llamadotable.blade.phpparapoderserincluidoseusaríalarutajuntoconelnombrequedandocomo@include('admin.users.table'),viewsnosecontemplapueseslaraizdelasvistas.

ParamasinformaciondeBladepodemosiraladocumentacionoficialdeLaravelsobretemplates.

Capítulo10.VistasymotordeplantillasBlade

47

Page 48: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

ControladoresEnlugardedefinirensutotalidadlalógicadelaspeticionesenelarchivoroutes.php,esposiblequedeseeorganizarestecomportamientousandoclasestipoController.LosControladorespuedeagruparlaspeticionesHTTPrelacionadaconlamanipulaciónlógicaenunaclase.LosControladoresnormalmentesealmacenaneneldirectoriodeaplicaciónapp/Http/Controllers/.

Uncontrollerusualmentetrabajaconlaspeticiones:

GET.POST.PUT.DELETE.PATCH.

Asociandolosmétodosdelasiguienteforma:

GET:index,create,show,edit.POST:store.PUT:update.DELETE:destroy.PATCH:update.

Loscontroladoresnosayudanaagruparestaspeticionesenunaclasequeseligaalasrutas,enelarchivoapp/Http/routes.php,paraestousamosuntipoderutallamanaresource:

Route::resource('pasteles','PastelesController');

Estarutanoscrearaungrupoderutasderecursosconlaspeticionesqueestasmencionadasarriba:index,create,show,edit,store,update,destroy.EstassonlasoperacionesmasusadasenunaclaseyparanotenerquecrearunarutaparacadamétodoesqueLaravelagrupatodoestoconunarutadetiporesourcequeseligaauncontrolador.

Estosmétodossignifican:

index:Eselmétodoinicialdelasrutasresource,usualmentelousamosparamostrarunavistacomopáginaprincipalquepuedeconteneruncatalogooresumendelainformacióndelmodeloalcualperteneceobiennomostrarinformaciónysolotenerlafuncióndepáginadeinicio.

Capítulo11.Controladores

48

Page 49: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

create:Estemétodolopodemosusarparadireccionarelsistemaalavistadondesevanarecolectarlosdatos(probablementeconunformulario)paradespuésalmacenarlosenunregistronuevo,usualmenteredirigealindex.

show:Aquipodemoshacerunnaconsultadeunelementodelabasededatosodetodosloselementosoregistrospormediodelmodelopararealizarunadescripcion.

edit:Estemétodoessimilaraldecreateporquelopodemosusarparamostrarunavistaquerecolectalosdatosperoadiferenciadecreateesconelfindeactualizarunregistro.

store:Aquiesdondeseactualizaunregistroenespecificoqueprovienedelmétodocreateynormalmenteredirigealindex.

update:Aligualqueelstore,soloqueenvezdeprovenirdecreateprovienedeedityenvezdecrearunnuevoregistro,buscaunexistenteylomodifica,tambiensueleredirigiralindex.

destroy:EnestemétodousualmentesedestruyeoeliminaunregistroylapeticiónpuedeprovenirdedondeseasiempreycuandoseallamadoconelmétodoDELETE,despuéspuederedirigiralindexoaotrositiodependiendosilogroeliminarono.

Ahoraestonoquieredecirqueuncontroladornecesariamentedebeejecutarestaspeticionesobligatoriamente,podemosomitirlasoinclusoagregarmas.

ParacrearcontroladoresenLaravelusamosartisanconelsiguientecomando:

phpartisanmake:controllerNameController

Elcomandoanteriorcrearauncontroladorenlacarpetaapp/Http/Controllers/quepordefectovaatenertodosestosmétodosdentrodesi,entoncesagregaremoslarutadetiporesourseanterioralarchivoderutasycorreremoselsiguientecomandoenlaconsola:

phpartisanmake:controllerPastelesController

Conestovamosapodertrabajarparacadamétododelcontroladorunarutaylasfuncionesinternassonlasquesevanaejecutar,elarchivocreadoseverádelasiguientemanera:

Capítulo11.Controladores

49

Page 50: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Enlalineadecomandospodemosvertodaslasrutasquenuestroproyectotieneregistradas:

phpartisanroute:list

Estecomandonosvaamostrarenlaconsolaunresultadosimilaraesto:

Capítulo11.Controladores

50

Page 51: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

aquipodemosverelnombredenuestrasrutas,dequetiposon,siesquerecibenparametrosycomosellaman,estainformaciónesmuyutilparapoderasociarlosmétodosdelcontroladorconlasrutasytambiencomoesquelasvamosausarenelnavegador.

Porejemplolarutapateles/{pasteles}detipoGETconelnombrepasteles.index,seasociaalafunciónindex()delcontroladorPastelesControlleryporconsecuenteloquehagamosenesafunciónlopodremosverenelnavegador.

Loscontroladoressonuntemacomplicadoyextensoasicomoelenrutamientoaunqueenelcursosolovimosenrutamientobasico,porlocualdejamosloslinksdeladocumentacionoficialdeControladoresydeEnrutamientoenlaversion5.1deLaravel.

Capítulo11.Controladores

51

Page 52: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

ValidacionesenLaravelExistenvariasformasdevalidarnuestraaplicaciónparacubriraspectosdeseguridadcomoSQLInjection,ataquesXSSoCSRF,algunasdeellasson:

Validacióndeladodelcliente(JavascriptyetiquetasHTML).Validaciónaniveldebasededatos(Migracionesymodelos).Validacióndeformularios(Request).

Validacióndelladodelcliente:Podemosvalidarqueloscamposdeunformularioseanrequeridosalagregarelatributorequired.

<formaction="demo_form.asp">

Username:<inputtype="text"name="username"required>

<inputtype="submit">

</form>

Elatributorequiredesunatributobooleano.Cuandoestapresente,esteespecificaqueuncampodebeserrellenadoantesdeserenviadoelcontenidodelformulario.

Elatributorequiredtrabajaconlossiguientestiposdeinput:

textsearchurltelemailpassworddatapickersnumbercheckbox

Elatributopattern

Consemencionoanteriormente,conrequiredsolosenecesitadecualquiervalorenelelemento<input>paraserválido,peroutilizandoelatributopatternenconjunto,selograqueseverifiquenosololapresenciadeunvalor,sinoqueestevalordebecontenerun

Capítulo12.ValidacionesenLaravel

52

Page 53: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

formato,unalongitudountipodedatoespecifico.Estoúltimoselogradefiniendounpatrónconexpresionesregulares.

<labelfor="tel">Teléfono10dígitosempezandopor228</label>

<inputtype="text"pattern="^228\d{8}$">

Parautilizarelatributopatternesrecomendableutilizareltype="text"ynountypedelospredefinidosenHTML5queyacuentanconpatronesdevalidaciónenelpropionavegador.Mezclarambospuedellevararesultadosinesperados.

ValidacióndeformulariosconpluginsJQuery

ElmejorpluginJQueryparavalidarformulariosesformvalidation.Sinembargoformvalidationesunpluginquetieneuncostodependiendolalicenciaquequeramosocupar.

Formvalidationescompatibleconlosformulariosdelosframeworkscssmáspopulares:

BootstrapFoundationPureSemanticUIOtros

SmokeeselmáscompletopluginJQuerydiseñadoparatrabajarconbootstrap3,ademásesopensourceeincluyelassiguientescaracterísticas:

Validacióndeformularios.Sistemadenotificaciones.Progressbar.Soporteparafullscreen.Agregarfuncionalidadextraalospanelesdebootstrap.Helpersparaconversióndetipos.

Paraincluirsmokeennuestroproyectosólotenemosquedescargarelplugindeaquí.

Extraerlosarchivosdelzip,ycolocarlosarchivosCSSyJSdentrodelacarpetapublic/assetsdenuestroproyectoenLaravel:

Capítulo12.ValidacionesenLaravel

53

Page 54: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

public/

assets/

css/

smoke.css

smoke.min.css

js/

smoke.js

smoke.min.js

lang/

es.js

es.min.js

Unavezhechoesto,debemoshacerreferenciaalosestilosyscriptsdesdenuestrodocumentohtmlenlaseccióndeheadybody:

<!DOCTYPEhtml>

<html>

<head>

<metacharset="utf-8">

<title>EjemploSmoke</title>

{!!Html::style('assets/css/smoke.css')!!}

</head>

<body>

{!!Html::script('assets/js/smoke.js')!!}

{!!Html::script('assets/lang/es.js')!!}

</body>

</html>

Losejemplossobrevalidaciones,notifiaciones,progressbar,etclosencontrarásenlapáginaoficialdeSmoke.

Validacióndelladodelservidor(Request).LaravelpermitevalidarlosdatosenviadosporunformulariodeformamuysencillaocupandounMecanismollamados"Requests".VeamosunejemploocupandoelcontrollerPastelesControllervistoenelcapítuloanterior,dandoleusoalosmétodosstoreyupdate,elfuncionamientoylógicapuedesverloenelAnexoC.CRUDconLaravelparacomprendersufuncionamiento:

LoprimeroquedebemoshacerescrearunrequestparaelmétodostoredePastelesControlleryaquenecesitamosvalidarquelosdatosenviadosenelformularioparacrearunnuevopastelseanválidos.

Ejemplo:

Capítulo12.ValidacionesenLaravel

54

Page 55: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

phpartisanmake:requestCrearPastelesRequest

ConestecomandoCrearemoselRequestCrearPastelesRequestubicadoen:

app/Http/Request/CrearPastelesRequest

Sucontenidoeselsiguiente:

<?php

namespaceCurso\Http\Requests;

useCurso\Http\Requests\Request;

classCrearPastelesRequestextendsRequest

{

/**

*Determineiftheuserisauthorizedtomakethisrequest.

*

*@returnbool

*/

publicfunctionauthorize()

{

returnfalse;

}

/**

*Getthevalidationrulesthatapplytotherequest.

*

*@returnarray

*/

publicfunctionrules()

{

return[

//

];

}

}

Losiguientequeharemosserácambiarelvalorqueregresaelmétodoauthorize()defalseatrueparapermitirqueelRequestlopuedaocuparcualquierusuario.

publicfunctionauthorize()

{

returntrue;

}

Capítulo12.ValidacionesenLaravel

55

Page 56: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Posteriormenteenelmétodorules()agregaremoslasreglasdevalidacióndelformularioparacrearpastelesquedandoasí:

publicfunctionrules()

{

return[

'nombre'=>'required|string|max:60',

'sabor'=>'required|in:chocolate,vainilla,cheesecake'

];

}

AlfinalelarchivoCrearPastelesRequestdeberáverseasí:

<?php

namespaceCurso\Http\Requests;

useCurso\Http\Requests\Request;

classCrearPastelesRequestextendsRequest

{

/**

*Determineiftheuserisauthorizedtomakethisrequest.

*

*@returnbool

*/

publicfunctionauthorize()

{

returntrue;

}

/**

*Getthevalidationrulesthatapplytotherequest.

*

*@returnarray

*/

publicfunctionrules()

{

return[

'nombre'=>'required|string|max:60',

'sabor'=>'required|in:chocolate,vainilla,cheesecake'

];

}

}

DeigualformacrearemoselRequestparaelmétodoupdatedePastelesController.

phpartisanmake:requestEditarPastelesRequest

Capítulo12.ValidacionesenLaravel

56

Page 57: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Yelarchivolodejaremoscomosemuestraacontinuación.

<?php

namespaceCurso\Http\Requests;

useCurso\Http\Requests\Request;

classEditarPastelesRequestextendsRequest

{

/**

*Determineiftheuserisauthorizedtomakethisrequest.

*

*@returnbool

*/

publicfunctionauthorize()

{

returntrue;

}

/**

*Getthevalidationrulesthatapplytotherequest.

*

*@returnarray

*/

publicfunctionrules()

{

return[

'nombre'=>'required|string|size:60',

'sabor'=>'required|in:chocolate,vainilla,cheesecake'

];

}

}

LasreglasdevalidaciónocupadasenelejemploanteriorlaspodemosencontrarexplicadasconmayordetalleenlapáginadeValidacionesdeLaravel.

ParaocuparelnuevorequestenPastelesControllerdebemosincluirlo:

useCurso\Http\Requests\CrearPastelesRequest;

useCurso\Http\Requests\EditarPastelesRequest;

EnelmodeloPastelagregaremosunapropiedad$fillableparaindicarqueatributosdelatablapastelespodránserocupadosconelmétodo$request->all().

Elmodelopastelesquedaríaasí:

Capítulo12.ValidacionesenLaravel

57

Page 58: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<?php

namespaceCurso;

useIlluminate\Database\Eloquent\Model;

classPastelextendsModel

{

protected$table='pasteles';

protected$fillable=['nombre','sabor'];

publicfunctionscopeSabor($query,$sabor){

return$query->where('sabor',$sabor);

}

publicfunctionscopeId($query,$id){

return$query->where('id',$id);

}

}

LosmétodosstoreyupdaterecibiráncomoparámetrounobjetoRequestparaaplicarlasreglasdevalidación,alfinalelcontroladorPastelesControllerdebetenerelsiguienteaspecto:

<?php

namespaceCurso\Http\Controllers;

useIlluminate\Http\Request;

useCurso\Http\Requests;

useCurso\Http\Controllers\Controller;

useCurso\Pastel;

useCurso\Http\Requests\CrearPastelesRequest;

useCurso\Http\Requests\EditarPastelesRequest;

classPastelesControllerextendsController

{

/**

*Displayalistingoftheresource.

*

*@returnResponse

*/

publicfunctionindex()

{

$pasteles=Pastel::get();

returnview('pasteles.index')->with('pasteles',$pasteles);

}

Capítulo12.ValidacionesenLaravel

58

Page 59: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

/**

*Showtheformforcreatinganewresource.

*

*@returnResponse

*/

publicfunctioncreate()

{

returnview('pasteles.create');

}

/**

*Storeanewlycreatedresourceinstorage.

*

*@returnResponse

*/

publicfunctionstore(CrearPastelesRequest$request)

{

$pastel=Pastel::create($request->all());

returnredirect()->route('pasteles.index');

}

/**

*Displaythespecifiedresource.

*

*@paramint$id

*@returnResponse

*/

publicfunctionshow($id)

{

//

}

/**

*Showtheformforeditingthespecifiedresource.

*

*@paramint$id

*@returnResponse

*/

publicfunctionedit($id)

{

$pastel=Pastel::find($id);

returnview('pasteles.edit')->with('pastel',$pastel);

}

/**

*Updatethespecifiedresourceinstorage.

*

*@paramint$id

*@returnResponse

*/

publicfunctionupdate(EditarPastelesRequest$request,$id)

{

$pastel=Pastel::find($id);

Capítulo12.ValidacionesenLaravel

59

Page 60: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

$pastel->fill($request->all());

$pastel->save();

returnredirect()->route('pasteles.index');

}

/**

*Removethespecifiedresourcefromstorage.

*

*@paramint$id

*@returnResponse

*/

publicfunctiondestroy($id)

{

$pastel=Pastel::find($id);

$pastel->delete();

Pastel::destroy($id);

returnredirect()->route('pasteles.index');

}

}

SiteinteresaverelprocesoconelcualsecompletaronlosmétodosterecomendamosiralAnexoC.CRUDconLaravelparamayorinformaciónyasípoderprobaradecuadamentelosRequest.

Capítulo12.ValidacionesenLaravel

60

Page 61: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

MiddlewaresEnestepuntodebemostenernuestroCRUDparalaclasePasteles,encasodenotenerlorecomiendoverelAnexoC.CRUDconLaravelparapodercontinuar.Ahorabiensiyapodemosrealizarlasoperacionesbásicasnopodemospensarenllevaraunambienterealocomercialunproyectoenestenivel.AunsifuncionacorrectamentenohemoscontempladotodoslosposiblescasosoamenazasqueseencuentranafueraenlaWeb,talescomosonhackers,estafadoresoinclusolasfallasusualesdelosusuariosfinales.

ParasolucionarestoLaravelutilizalosMiddleware,quenospermitenprotegerlasrutasdeaccesosnoautorizados,comosunombreloindica(middle)seubicaenelmediodelapeticion(Request),entoncessideseamosagregarunnuevoniveldeseguridadanuestrosistemalosMiddlewaresonlarespuesta.

PrimerovamosaanalizarunMiddlewareparalaautenticacionologueodelosusuariosennuestrasrutas.PordefectoennuestroproyectodeLaraveldebemosdecontarconunmiddlewarellamadoauth,estemiddlewaredeloqueseencargaesdeverqueelusuarioseencuentreconunasesionactiva,recuerdenqueenLaravelyatenemospordefectoelmanejodesesionesjuntoconlastablasdelabasededatos.Paradecirleanuestroproyectoquelasrutasdenuestrocontroladordepastelesvanaestarprotegidasporelmiddlewareauthusamoselmétodomiddleware('name');dentrodelconstructordenuestraclasedelasiguienteforma:

publicfunction__construct(){

$this->middleware('auth');

}

RecuerdenqueestodebeubicarsedentrodenuestrocontroladorPastelesControllercomounafunciónmas,usualmenteestafuncióneslaprimeraqueseveporlocualrecomiendoquealmomentodeagregarestecodigolohaganeliniciodesuclase.

Conestecambiosedarancuentadequesiingresanalasrutasenlascualesyaantespodiamosvernuestrocrudlosredirigeallogin,sicreanunacuentadeusuarioylointentannuevamenteveranqueelaccesoyaselesvaaconceder,ademáselnombreyusuarioconelqueaccedanseveraenlabarrasuperiordenavegacionalladoderecho,comprobandolassesionesqueLaravelnosdacomounregalo.

Analizaremosunpocolosarchivos,siempreesimportantesabercomofuncionaloqueestamosusandoynoquedarnossoloconlaideadequefuncionasintenerlamasremotaideadeloquesucede.Silaautenticaciónyaestahechaestolopodemosverificarenel

Capítulo13.Middlewares

61

Page 62: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

archivoKernel.phpdentrodelarutaapp/Http/,enestearchivovamosaveruncodigosimilaraeste:

enelpodemosverunavariableprotegidallamada$routeMiddlewaredondeestandefinidoslosmiddlewaredelsistema,podemosobservartantolaubicacioncomoelnombreconelcualpodemosusarlo,estossonauth,auth.basicyguest.

ElarchivoquehacereferenciaalmiddlewareauthsellamaAuthenticate.phpqueseencuentraenapp/Http/Middleware/,dentrodeestearchivopodemosobservarlaestructuradeunMiddlewarenormal,estetipodearchivoscuentanconunafunciónllamadahandle()queeslaqueseejecutacuandosellamaalmiddleware,lafunciónhadledeestearchivoeslasiguiente:

Capítulo13.Middlewares

62

Page 63: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Enellapodemosobservarquerealizaunaseriedepreguntasparasaberquerespuestadaryadonderedirigir,primeropreguntasielusuarioestalogueadoconlapreguntaif($this->auth->guest()),guestsignificainvitadoyporlógicasiestainvitadoquieredecirquenocuentaconunasesioniniciada.SiesefueraelcasoentoncesdebemosverificarsiellogueoseintentarealizarpormediodeAJAXysilapeticionesdeestetipoentoncesrechazarlaymandarunarespuestadeaccesonoautorizado,perosinoesdetipoAJAXentoncesredirigirdirectoalavistadelogueo.Enelcasodequenoseauninvitadoentoncesquieredecirquesitieneiniciadasusesionporlocualpasaralapeticiónalsiguientemiddlewarehastaquelleguealúltimoyterminelasverificacionesdelsistema.

CreandonuestrospropiosMiddlewares

PreparativosAhorabien,estonoeslasoluciónatodosnuestrosproblemas(aun),aunqueeltenerlaautenticaciónhechapordefectoesunagranayudapodemosrequerirmásprotección,porejemplosimanejamosrolesennuestraaplicación,digamosqueelCRUDdepastelessololopodemosversitenemosunacuentadeadministradorenelsistemaperonositenemosunacuentanormal.

Vamosamodificaralgunosarchivosparapoderaplicarnuestronuevomiddleware,primerolamigraciondeusuariosllamadacreate_users_table.phpenlacarpetadelasmigraciones,vamosaagregaruncampodetipodeestaforma:

Capítulo13.Middlewares

63

Page 64: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<?php

useIlluminate\Database\Schema\Blueprint;

useIlluminate\Database\Migrations\Migration;

classCreateUsersTableextendsMigration

{

/**

*Runthemigrations.

*

*@returnvoid

*/

publicfunctionup()

{

Schema::create('users',function(Blueprint$table){

$table->increments('id');

$table->string('name');

$table->string('email')->unique();

$table->string('password',60);

$table->enum('type',['admin','user']);

$table->rememberToken();

$table->timestamps();

});

}

/**

*Reversethemigrations.

*

*@returnvoid

*/

publicfunctiondown()

{

Schema::drop('users');

}

}

PeroenelmodelodeUsersquevienepordefectoconLaravel5sedefinenloscamposquesepuedenllenarylosocultos,vamosadecirlealmodeloquetambienpuedellenarelcampotypedeestaforma:

protected$fillable=['name','email','password','type'];

ElmodeloUserseencuentraenapp/Http/,ahorarevisaremoselcontroladorderegistro,esdecirelcontroladorAuthControllerenlacarpetaapp/Http/Controllers/Auth/,buscaremoselmétodocreateyvamosadejarlodeestaforma:

Capítulo13.Middlewares

64

Page 65: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

protectedfunctioncreate(array$data)

{

returnUser::create([

'name'=>$data['name'],

'email'=>$data['email'],

'password'=>bcrypt($data['password']),

'type'=>$data['type'],

]);

}

Hastaahorasoloestamosdiciendolealmétodoqueagregueotroelementoquevaaprovenirdelavistallamado'type'.

Ahoranecesitamospodercrearunadministradorounusuarionormal,porestovamosaagregaruncamposelectennuestravistaderegistroparacompletarlasmodificaciones,vamosamodificarlavistaregister.blade.phpdentrodelacarpetaresources/views/auth/.Levamosaagregarelcampoydeberaversedeestaforma:

@extends('app')

@section('content')

<divclass="container">

<divclass="row">

<divclass="col-md-6col-md-offset-3">

<divclass="panelpanel-default">

<divclass="panel-heading">SignUp</div>

<divclass="panel-body">

{!!Form::open(['route'=>'auth/register','class'=>'form'])!!

}

<divclass="form-group">

<label>Name</label>

{!!Form::input('text','name','',['class'=>'form-contr

ol'])!!}

</div>

<divclass="form-group">

<label>Email</label>

{!!Form::email('email','',['class'=>'form-control'])!

!}

</div>

<divclass="form-group">

<labelfor="type">Type</label>

<selectname="type"class="form-control">

<optionvalue=""disabledselected>Eligeunaopcion...

</option>

<optionvalue="admin">Administrador</option>

<optionvalue="user">Usuarionormal</option>

Capítulo13.Middlewares

65

Page 66: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

</select>

</div>

<divclass="form-group">

<label>Password</label>

{!!Form::password('password',['class'=>'form-control'])

!!}

</div>

<divclass="form-group">

<label>Passwordconfirmation</label>

{!!Form::password('password_confirmation',['class'=>'fo

rm-control'])!!}

</div>

<div>

{!!Form::submit('send',['class'=>'btnbtn-primary'])!!

}

</div>

{!!Form::close()!!}

</div>

</div>

</div>

</div>

</div>

@endsection

CrearelmiddlewareIsAdminConloanteriortendremostodosloscambiosnecesariosparaadministrarrolesennuestrosistema.LosiguienteescrearelmiddlewareisAdmin,paraestoartisannoproveeestecomando:

phpartisanmake:middlewarename

Elcomandoparanuestroejemploseriaigualaesto:

phpartisanmake:middlewareIsAdmin

estonosvaacrearunarchivodentrodelacarpetaapp/Http/Middleware/conelnombrequeledimosconlafunciónhandlequeexplicamosanteriormente.Parapoderverificarsielusuariologueadoesunadministradordebemospoderobtenerelusuarioporlocualvamosaagregarunaclaseparapoderobtenereseusuario,inyectaremosladependencia,vamosacrearunatributoqueserálaautenticaciónquevienedelmiddlewareanterioryelconstructordeestaforma:

Capítulo13.Middlewares

66

Page 67: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<?php

namespaceCurso\Http\Middleware;

useIlluminate\Contracts\Auth\Guard;

useClosure;

classIsAdmin

{

protected$auth;

publicfunction__construct(Guard$auth)

{

$this->auth=$auth;

}

/**

*Handleanincomingrequest.

*

*@param\Illuminate\Http\Request$request

*@param\Closure$next

*@returnmixed

*/

publicfunctionhandle($request,Closure$next)

{

if($this->auth->user()->type!='admin'){

$this->auth->logout();

if($request->ajax()){

returnresponse('Unauthorized.',401);

}else{

returnredirect()->to('auth/login');

}

}

return$next($request);

}

}

ParalalógicapodemosemularloquepasaenelMiddlewaredeAuthenticate,vamosapreguntareltipodeusuarioyvamosapreguntarsilapeticionesAJAXparadirigirlarutadelapeticionadondeseaelcaso,sielusuarioesdetipoadminentoncesvamosaredirigirlapeticionalsiguienteMiddleware,sinoentoncesvamosacerrarlasesionypreguntaremossilapeticionesAJAX,encasodeserAJAXvamosadenegarla,sinoentoncesvamosamandarallogin.Usaremoslafunción->to();porquesinosquedamosconlafunciónguest()esoguardalarutadedestinoalaquequeremosllegarynuncavamosapoderiniciarsesionconusuariosnormales.

Capítulo13.Middlewares

67

Page 68: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Ahoravamosaregistrarnuestromiddlewareparapoderusarloyaqueporsimismonolovamosapoderintegraralcontrolador,paraestotenemosquemodificarelKernel.php,lounicoaquiesagregarenel$routeMiddlewareunnombreparanuestroMiddlewareylaubicaciondelmismo,asiescomoseveria:

protected$routeMiddleware=[

'auth'=>\Curso\Http\Middleware\Authenticate::class,

'auth.basic'=>\Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,

'guest'=>\Curso\Http\Middleware\RedirectIfAuthenticated::class,

'is_admin'=>\Curso\Http\Middleware\IsAdmin::class,

];

EntoncesconestoyapodemosligarloalcontroladordentrodesuconstructoryparacadafuncióndentrodeestesevaamandarallamarelMiddlewareis_admin:

publicfunction__construct(){

$this->middleware('auth');

$this->middleware('is_admin');

}

Asipodemosprobarentrandoaunarutaconunacuentadeusuarionormalydenuevoconunacuentadeadministrador,entoncesveremosquesolosiusamosunacuentadeadministradorpodemosverloqueyateniamosalinicioperodeotromodocerrarálasesiónynonosdejaraentraraverelcontenido.

ParamasinformacionleanladocumentacionoficialsobreMiddlewaresdeLaravel5.

Capítulo13.Middlewares

68

Page 69: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

¿QuéesHTML5?HTML5eslanuevaversióndellenguajedemarcadoqueseusaparaestructurarpáginasweb,actualmentesigueenevolucion,HTML5incorporacaracterísticasnuevasymodificacionesquemejorarásignificativamentelaformadeconstruirsitiosweb.

HTML5nospermitecreardocumentosHTMLdeunaformamássimplificadaysencillaquesusversionesanteriores.

¿QuéhaydenuevoenHTML5?LadeclaraciónDOCTYPEesahoramássimple:

<!DOCTYPEhtml>

Lacodificacióndecaracteressehacedelasiguientemanera:

<metacharset="UTF-8">

Nuevostags(etiquetas)

Nuevoselementossemánticoscomo:<header>,<footer>,<article>,y<section>.Nuevoselementosparaelcontroldeformularios:number,date,time,calendar,yrange

Nuevoselementosgráficos:<svg>y<canvas>.Nuevoselementosmultimedia:<audio>y<video>.

NuevasAPI's

HTMLGeolocationHTMLDragandDropHTMLLocalStorageHTMLApplicationCacheHTMLWebWorkersHTMLSSE

AnexoA.HTML5

69

Page 70: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

PlantillabásicadeundocumentoenHTML5CualquierdocumentoenHTML5debecontenerlasiguienteestructurabásica.

<!DOCTYPEhtml>

<html>

<head>

<metacharset="UTF-8">

<title>Títulodelapágina</title>

</head>

<body>

Cuerpodeldocumento

</body>

</html>

Enlaseccióndelacabecera<head>escribiremos:

Lacodificaciónqueocuparemosparaeldocumento,esrecomendadousarUTF-8.EltítulodelapáginaLoselementoslinkparautilizarlosarchivosCSS.

Enlaseccióndelcuerpo<body>escribiremos:

BarrádenavegaciónEncabezadosSeccionesParrafosElementosmultimedia:audio,video,imgTextoennegritas,cursivaysubrayado.TablasListasFormulariosHipervínculosetc.

EncabezadosLosencabezadosenhtmltienen6tamañosdiferentesyseescribendelasiguienteforma:

AnexoA.HTML5

70

Page 71: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

HTML Resultado

Secciones(divisiones)Podemosdividirnuestrodocumentoenseccionesdistintasconlaetiqueta<div>paratenerunmayorordensobrenuestrodocumentoyaplicardiferentesestilossegúnlasección.

HTML Resultado

FormatodetextoPodemosdefinirdiferenteselformatodeltextocomo:negrita,cursiva,subrayado,tipodeletra,tamañodefuente,saltosdelínea,párrafos,citas,etc.

AnexoA.HTML5

71

Page 72: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

HTML Resultado

<b> Textoennegrita

<i> Textoencursiva

<u> Textosubrayado

<p> Parrafo

<code>Escribirenformatocódigodeprogramación

<p> Parrafo

<em> Textoconénfasis

<br> Saltodelínea

<!--Texto--> ComentariosenlenguajeHTML

<hr> Líneahorizontalparadividirsecciones<fontface="verdana"size="10"

color="red">Formateartexto

FormulariosHTML Resultado

<form> DefineunFormularioHTML

<input>

<textarea> Defineuntextareaparaguardarunagrancantidaddetexto.

<button> Defineunbotón

<select> Defineunalistadesplegable

<option> Defineunaopciónenunalistadesplegable

<label> Defineunaetiquetaparauninput

AtributosdelosformulariosSeccionendesarrollo.

AnexoA.HTML5

72

Page 73: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

TablasEjemplodeunatablabásica:

<table>

<thead>

<tr>

<th>cabecera</th>

<th>cabecera</th>

<th>cabecera</th>

</tr>

</thead>

<tfoot>

<tr>

<td>celda</td>

<td>celda</td>

<td>celda</td>

</tr>

</tfoot>

<tbody>

<tr>

<td>celda</td>

<td>celda</td>

<td>celda</td>

</tr>

</tbody>

</table>

Lastablasseescribenconlaetiqueta<table>,dentrodelatablatendremosfilasycolumnas,laetiqueta<tr>definelasfilasylaetiqueta<td>definelascolumas.

HipervínculoseimágenesLasimágenespuedenserdeformatopng,jpgogifyseescribenconlaetiqueta<img>entresusprincipalesatributostenemos:

src:LaURIalaimágen.alt:Textoquesedesplegaráencasodequelaimagennoseadesplegada.width:Anchodelaimagen,puedeserescritaenpixelesoenporcentaje.height:Altodelaimagen,puedeserescritaenpixelesoenporcentaje.

Ejemplo:

<imgsrc="html5.gif"alt="HTML5Icon"width="128"height="128">

AnexoA.HTML5

73

Page 74: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

LosHipervínculosolinkssondefinidosconlaetiqueta<a>quecuentaconlossiguientesatributos:

href:especificalaURIdedestino.target:especificaendóndeseabriráelnuevodocumentodellink.

_blank:Abreelnuevodocumentoenunanuevaventanaopestaña._self:Abreelnuevodocumentoenelmismoframe(acciónpordefecto)._parent:Abreelnuevodocumentoenelframepadre._top:Abreelnuevodocumentoentodoelcuerpodelaventana.

Ejemplodeunlink:

<ahref="https://www.facebook.com/oca159">Facebook</a>

Dentrodelasetiquetas<a>puedeiruntextoounaimagen.

<ahref="default.asp">

<imgsrc="smiley.gif"alt="HTMLtutorial">

</a>

Loshipervínculostambiénpuedenredireccionaraunsegmentoespecíficodelapáginaweb.

Ejemplo:Primerocreamosunasecciónconunatributoid.

<divid="Encabezado">Seccióndeencabezado</div>

Entoncesagregamosunlinkquenosenvíeaesaseccióndelapágina.Paralograresteobjetivo,agregamosenelatributohrefeliddelasecciónprecedidodeunsigno#.

<ahref="#Encabezado">Visitarlaseccióndeencabezado</a>

AprendermássobreHTML5ParaprofundizarunpocomásenHTML5esrecomendableeltutorialdew3schools.

AnexoA.HTML5

74

Page 75: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

CSS3(Hojasdeestiloencascada)EsunlenguajeusadoparadefinirycrearlapresentacióndeundocumentoestructuradoescritoenHTMLoXML.

Laideaessepararelcontenido(Texto)desupresentación(formato).

LainformacióndeestilopuedeserdefinidaenundocumentoseparadooenelmismodocumentoHTML.Enesteúltimocasopodríandefinirseestilosgeneralesenlacabeceradeldocumentooencadaetiquetaparticularmedianteelatributo<style>.

SintaxisUnahojadeestilosecomponedeunalistadereglas.Cadareglaoconjuntodereglasconsisteenunoomásselectoresyunbloquededeclaración(o«bloquedeestilo»)conlosestilosaaplicarparaloselementosdeldocumentoquecumplanconelselectorquelesprecede.Cadabloquedeestilossedefineentrellaves,yestáformadoporunaovariasdeclaracionesdeestiloconelformatopropiedad:valor;.

EnelCSS,losselectoresmarcaránquéelementosseveránafectadosporcadabloquedeestiloquelessiga,ypuedenafectaraunoovarioselementosalavez,enfuncióndesutipo,nombre(name),ID,clase(class),posicióndentrodelDocumentObjectModel,etcétera.

AbajopuedeverseunejemplodeunapartedeunahojadeestilosCSS:

selector[,selector2,...][:pseudo-class][::pseudo-element]{

propiedad:valor;

[propiedad2:valor2;

...]

}

/*comentarios*/

Unconjunodereglasconsisteenunselectoryunbloquededeclaraciones.

AnexoB.CSS

75

Page 76: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

FormasdeinsertarCSSennuestrodocumentoHTMLExisten3formasdeinsertarCSS:

Unahojadeestiloexterno(Archivoconextensión.css).Unahojadeestilointerna(DentrodelHTMLocupandoeltag<style>).Estiloinline(usandoelatributostylesobreunelementoHTML).

Hojadeestiloexterna

PodemosescribirnuestroCSSenunarchivodenuestrosistemaconextensión.css,paraincluirunareferenciaalahojadeestiloexternaescribiremoslarutadentrodelatributohrefdelaetiqueta<link>,esconvenienteescribirestadefinicióndentrodelaetiqueta<head>.

<head>

<linkrel="stylesheet"type="text/css"href="mystyle.css">

</head>

Hojadeestilointerna

Unahojadeestilosinternapuedeserusadasiunaúnicapáginatieneunúnicoestilo.

Lashojasdeestilointernassondefinidasdentrodelaetiqueta<style>yenlaseccióndelaetiqueta<head>.

AnexoB.CSS

76

Page 77: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<head>

<style>

body{

background-color:linen;

}

h1{

color:maroon;

margin-left:40px;

}

</style>

</head>

Estilosinline

Unestiloinlinepuedeserusadoparaaplicarunúncioestiloparaunúnicoelementodeunapágina.

Parausarestilosinline,agregamoselatributostylealelementohtml.

<h1style="color:blue;margin-left:30px;">Thisisaheading.</h1>

ComentariosenCSSLoscomentariossonunaformadeexplicarydocumentarelcódigo,puedenserdeutilidadcuandoqueremoseditarelcódigotiempodespués.Loscomentariossonignoradosporelnavegador.

EnCSSuncomentarioempiezacon/*yterminacon*/.

p{

color:red;

/*Thisisasingle-linecomment*/

text-align:center;

}

/*Thisis

amulti-line

comment*/

Selectores

AnexoB.CSS

77

Page 78: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

CSS3puedeaplicardiferentesestilosaungrupodeelementosHTMLdependiendoeltipodeselectorqueocupemos,veremoscadaunodeellos.

Selectorporelemento

Seleccionaelementosbasándoseenelnombredelelemento.

Porejemploparaseleccionartodosloselementos<p>deunapáginayaplicarleselestilo:textoalineadoalcentroydecolorrojo.

p{

text-align:center;

color:red;

}

Selectorporid

ElselectorporidutilizaelatributoiddeunelementoHTMLparaespecificarelelementoalqueselevaaaplicarunestilo.

CadaidesunvalorúnicodentrodeunapáginaHTML,porlocuállaselecciónsóloseaplicarásobreunúnicoelementoenparticular.

Paraseleccionarunelementoconunidespecifico,escribeunsignodenumeralogatoseguidoporelvalordeliddelelemento.

LasiguientereglaseaplicaráaunelementoHTMLconelid="dato1".

#dato1{

text-align:center;

color:red;

}

Elnombredeunidjamásempiezaconunnúmero,aligualqueladefinicióndevariablesenloslenguajesdeprogramación.

Selectorporclase

ElselectorporclaseseleccionatodosloselementosHTMLconunatributoclassespecífico.

Paraseleccionarelementosconunaclaseespecífica,escribimosunpuntoseguidoporelnombreelnombredelaclase.

AnexoB.CSS

78

Page 79: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

EnelejemplodeabajoseleccionaremostodosloselementosHTMLconclass="center"ylosalinearemosalcentro.

.center{

text-align:center;

color:red;

}

DeigualformaesposibleseleccionarelementosdeuntipoHTMLenespecificoyluegoaquellosconunaclaseenparticular.

Enelejemplodeabajoseleccionaremoslosparrafosconclass="center"ylosalinearemosalcentro.

p.center{

text-align:center;

color:red;

}

Aligualquelosids,lasclasesnodebennombrarseempezandoconunnúmero.

Agruparselectores

Enelcasodequetuvieramosvariosseleccionesqueapliquenelmismoestilo:

h1{

text-align:center;

color:red;

}

h2{

text-align:center;

color:red;

}

p{

text-align:center;

color:red;

}

Podemosreducirelcódigoagrupandolosselectoresseparandocadaselectorporunacoma.

AnexoB.CSS

79

Page 80: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

h1,h2,p{

text-align:center;

color:red;

}

AprendermássobreCSS3ParaaprendermássobretodosaspropiedadesyvaloresexistentesenCSS3asícomoguíassobrediseñoresponsivoyotrostemasrecomendamosvisitarlapáginaw3schools.

AnexoB.CSS

80

Page 81: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

CreaciondelCRUDconLaraveldesde0EsteanexodellibrodeLaravel5estapensadopararesumirelcontenidodeunaformaaplicada,demodoquesepuedanverenconjuntotodoslosconocimientosadquiridosduranteelcurso.

Seexplicaraelprocesoparadaraltas,bajas,cambiosyconsultasdelatablapastelesoCRUDquesignificaCreate,Read,UpdateandDeleteporsussiglaseningles.

Primeroretomaremoslasmigracionesylosseeders,creandolamigracionyunpequeñoseederparapoblarnuestraBD.

Paracrearlamigracionconlaplantillabasicausaremoselcomando

phpartisanmake:migrationcrear_tabla_pasteles--create=pasteles

Ahoradentrodelamigracionvamosadefinirlaestructuradelatablaquetendrasolocuatrocamposqueseran:id,nombre,saborytimestamps(estoenBDesigualacreated_atyupdated_at).

Dandounresultadocomolosiguiente:

AnexoC.CRUDconLaravel

81

Page 82: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<?php

useIlluminate\Database\Schema\Blueprint;

useIlluminate\Database\Migrations\Migration;

classCrearTablaPastelesextendsMigration

{

/**

*Runthemigrations.

*

*@returnvoid

*/

publicfunctionup()

{

Schema::create('pasteles',function(Blueprint$table){

$table->increments('id');

$table->string('nombre',60);

$table->enum('sabor',['chocolate','vainilla','cheesecake']);

$table->timestamps();

});

}

/**

*Reversethemigrations.

*

*@returnvoid

*/

publicfunctiondown()

{

Schema::drop('pasteles');

}

}

Ahoracrearemoselseederconelcomando:

phpartisanmake:seederPastelesSeeder

yvamosausarelcomponenteFakerparacrear50pastelesdeformaautomatica,elarchivofinalquedaradelasiguienteforma,recuerdenqueparausarFakeresnecesarioimportarlaclaseconlaintruccionuse:

AnexoC.CRUDconLaravel

82

Page 83: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<?php

useIlluminate\Database\Seeder;

useFaker\FactoryasFaker;

classPastelesSeederextendsSeeder

{

/**

*Runthedatabaseseeds.

*

*@returnvoid

*/

publicfunctionrun()

{

$faker=Faker::create();

for($i=0;$i<50;$i++){

\DB::table('pasteles')->insert(array(

'nombre'=>'Pastel'.$faker->firstNameFemale.''.$faker->las

tName,

'sabor'=>$faker->randomElement(['chocolate','vainilla','cheeseca

ke']),

'created_at'=>date('Y-m-dH:m:s'),

'updated_at'=>date('Y-m-dH:m:s')

));

}

}

}

Conestoyatendremoslaestructuradelatablayunseederparapoblar,conestoahorausaremoselsiguientecomandoparacrearlatablaenlaBDyllenarla:

phpartisanmigrate--seed

AhoravamosapasaracrearelModelo,elcualnosvaaservirparamapearlatabladelaBDaunaclasedeLaravelcomolovimosenelcapítulo7.Vamosausarelcomando:

phpartisanmake:modelPastel

Laravelnosrecomiendaseguirlasconvencionesparafacilitarnoseltrabajo,porloquelastablasdelaBasededatosdebenencontrarseennotacionunderscoreyenplural,ylosmodelosdebenencontrarseennotacionUpperCamelCaseyensingular.

ConestoLaravelnoscrearaelarchivoPastel.phpenlacarpetaapp/,siseguimoslasconvencionesdeLaravelpordefectoestoserialouniconecesario,perodebidoaquenuestrolenguajenoconviertelaspalabrasapluraldelamismaformaqueelingles

AnexoC.CRUDconLaravel

83

Page 84: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

entoncesdebemosdefiniralmodeloconquetablavaaestartrabajando.Agregaremosdentrodelmodeloelatributoprotected$table='pasteles';,yesoseriatodoparaelmodelo,quedandodelasiguientemanera:

<?php

namespaceCurso;

useIlluminate\Database\Eloquent\Model;

classPastelextendsModel

{

protected$table='pasteles';

}

Yatenemoslistonuestromanejodedatos,ahoravamosaprocederacrearnuestrasvistasparaquedesdeelnavegadorpodamosmandarlainformacionyuncontroladorparapoderdefinirnuestrasoperaciones,ademasdeespecificarlasrutasdenuestrosistema.

Paracomenzarvamosacrearnuestrocontroladorconelcomando:

phpartisanmake:controllerPastelesController

Laravelautomaticamentecreaunarchivodentrodelarutaapp/Http/Controllersconelnombrequeespecificamosydentrodeellasfuncionesparalosmetodos:index,create,store,show,edit,update,delete.Estosmetodoslosvamosadefinirmasadelante,porelmomentovamosacrearennuestroarchivoderutasungrupoderutasasociadasacadaunodelosmetodosdelcontroladorqueacabamosdecrear,estosehaceconunarutadetipoResourceorecurso,modificandoelarchivoroutesagregandoelsiguientecodigo:

Route::resource('pasteles','PastelesController');

Conestoyatendremosnuestrocontrolador(aunvacio)ynuestrasrutasdelsistema,locualpodemosverificarconelcomando:

phpartisanroute:list

Ahoravamosaterminardellenarnuestrocontrolador,debemosimportarlaclasePastelanuestrocontroladorparapoderhacerusodelModeloyasitrabajarconlabasededatos,estoconlaayudadeEloquent,comovimosduranteelcursoparacrearunnuevoregistroconEloquentbastacondefinirunavariabledeunnewModelo,enestecasoPastel,segun

AnexoC.CRUDconLaravel

84

Page 85: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

sedescribeenelcapitulo11losmetodosrespondenaunarutaenespecificodelarutaresourcequeagregamosenroutes.php,paraestecasovamosadefinircadaunodeellosenorden:

Index-PaginadeInicio

CuandoentramosaunapaginaprincipaldeadministracionsepuedenverenocasioneslainformacionqueseencuentraenlaBDyaccesoalasoperacionesbasicasdelCRUD,porlocualdebemossercapacesderecibirenelindexlosregistrosdelaBD.Dentroelmetodoindex(),vamosausaEloquentparaobtenertodoslospastelesyenviarlosaunavistaquevamosadefinirmasadelante,quedandodelasiguienteforma:

publicfunctionindex()

{

$pasteles=Pastel::get();

returnview('pasteles.index')->with('pasteles',$pasteles);

}

EloquentnosfacilitamucholasconsultasalaBDyhacequeseaportablenuestrocodigo,enelmetododecimosqueseleccionetodoslospastelesyosenvieaunavistallamaindexubicadaenlacarpetaresoures/views/pasteles/,comovimosenelcapitulo10lasrutasenbladecambianla/(diagonal)porun.(punto),lafuncionview('pasteles.index');tomacomocarpetaraizaresources/views/porloquenotenemoslanecesidaddeagregarloenlaruta.Ademasseestaconcatenandoelmetodowith('nombre',$var);quecomoprimerparametropideelnombreconelcualsevaapoderusarunavariabledelladodelavista,ycomosegundoparametrorecibelavariablequesevaamandaralavista.

Create-Paginaderegistro

EstemetodoesmuysencillopuestoquesolovaadevolverunavistasinningunavariableniusodeEloquent,porlocualquedadelasiguientemanera:

publicfunctioncreate()

{

returnview('pasteles.create');

}

Store-Funciondealmacenamiento

Estemetodoesdondedespuesdehaberentradoacreateserecibenlosdatosyseguardanenlabasededatos,parapoderrecibirlainformacionenesteejemplovamosausarlaclaseRequestquesignificapeticionyesunaclasequeLaravelagregapornosotros

AnexoC.CRUDconLaravel

85

Page 86: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

cuandocreamoselcontrolador,vamosapasarporparametrolapeticionenelmetododefiniendoqueesunavariabledelaclaseRequestydespuesdeesopodemosrecuperarporelnombredelcampodelformulario(atributoname)lainformacionenviada,entonceselmetodoquedariadelasiguienteforma:

publicfunctionstore(Request$request)

{

$pastel=newPastel;

$pastel->nombre=$request->input('nombre');

$pastel->sabor=$request->input('sabor');

$pastel->save();

returnredirect()->route('pasteles.index');

}

EnlafuncionestamoscreandounainstanciadeunnuevoPastelyasignandolosatributosdelaclasequesellamanigualqueloscamposdelaBDlosvaloresdelformularioconlavariablerequestyelmetodoinput('name');querecibecomoparametroelnombredelcampodelformulario,paramasdetallereviselasecciondelAnexoAdeHTMLquehablasobrelosatributosdelosformularios.

Despuesdeasignarlosvaloresdelapeticionalavariable$pastel,seusaelmetodosave();paraqueelmodeloseencarguedeguardarlosdatosenlaBDyfinalmenteredireccionaralindexconlosmetodosencadenados:redirect()->route('pasteles.index');.

Show-Paginadedescripcion

Losentimos,seccionendesarrollo.

Edit-Paginadeedicion

Lafunciondeeditessimilaraladecreatepuessolomuestraunavista,conunapequeñadiferencia,lacualesquesevaabuscarelpastelquesequiereeditarysevaamandaralavista,estoesobiopuesdebemospoderverlainformacionquevamosaeditar.Lafuncionquedariadelasiguienteforma:

publicfunctionedit($id)

{

$pastel=Pastel::find($id);

returnview('pasteles.edit')->with('pastel',$pastel);

}

AnexoC.CRUDconLaravel

86

Page 87: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Esmuyclaro,enunavariableseguardaelpastel,graciasalmodeloestosesolucionafacilmenteconelmetodofind(),eliddelpastelsemandaenlaurl,ahorabiensiestoespreocupantepuestoqueelidsevedirectamenteenlaURLrecordemosqueestonomodificaaun,solonosmandaalapaginaquevaapoderhacerunanuevapeticionparaactualizar.

Update-Funciondeactualizacion

Bien,despuesdeentrarenlapaginadeeditvamosapodereditarlainformacionyregresarlaalcontroladorparaqueefectueloscambios,dentrodelmetodoupdatevamosarecuperarnuevamenteelPastelpormediodesuidquetambienvaenlaurlyserecibecomoparametrodelafuncion,ademasvamosaagregarotroparametroqueseraelRequestaligualqueenlafuncioncreatepararecuperarlainformaciondelladodelclienteenelcontrolador,dejandolafunciondeestaforma:

publicfunctionupdate(Request$request,$id)

{

$pastel=Pastel::find($id);

$pastel->nombre=$request->input('nombre');

$pastel->sabor=$request->input('sabor');

$pastel->save();

returnredirect()->route('pasteles.index');

}

Estafuncionessimilaraladecreatelounicoquecambiaesqueenvezdecrearunnuevopastelvamosarecuperarunoexistenteycambiarsusatributos.

Destroy-Funciondeborrado

EstemetodotienelafunciondeeliminarelregistrodelaBD,peroparaefectuarlotenemosdosopciones,laprimerforma:crearunavariable$pastelydespuesusarelmetododelete()deEloquent.obienlasegunda:directamentedelmodelousarelmetododeEloquentdestroy($id),queseencargadedirectamentebuscaryeliminarelregistro,finalmentevamosaredirigiralindex,elmetodoalfinalquedaradelasiguienteforma:

AnexoC.CRUDconLaravel

87

Page 88: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

//Estaeslaprimeropcion

publicfunctiondestroy($id)

{

$pastel=Pastel::find($id);

$pastel->delete();

returnredirect()->route('pasteles.index');

}

//Estaeslasegundaopcion

publicfunctiondestroy($id)

{

Pastel::destroy($id);

returnredirect()->route('pasteles.index');

}

VistasdelCRUDEstassonlaultimapartequevamosacrear,primerodebemosprepararlosdirectoriosylosarchivosqueusaremos.

Laestructuradelacarpetaquedariadelasiguienteforma:

resources/

views/

pasteles/

partials/

fields.blade.php

table.blade.php

create.blade.php

edit.blade.php

index.blade.php

UsaremoseltemplatepordefectodeLaravelllamadoapp.blade.phpquefuimosmodificandoduranteelcursoporlocualsolodeberemoscrearlosarchivosrestantes.

Ahoraenelarchivoapp.blade.phpvamosamodificarloparaqueelcontenidoestemejoracomodadousandoBootstrapyvamosaagregarlosestilosyscriptsparaquelatabladondevamosamostrarelcontenidofuncionecomounDataTable,dejandoelarchivoappdelasiguienteforma:

TemplateApp

AnexoC.CRUDconLaravel

88

Page 89: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<!DOCTYPEhtml>

<htmllang="en">

<head>

<metacharset="utf-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width,initial-scale=1">

<title>Laravel</title>

@section('styles_laravel')

{!!Html::style('assets/css/bootstrap.css')!!}

{!!Html::style('assets/css/datatable-bootstrap.css')!!}

<!--Fonts-->

<linkhref='//fonts.googleapis.com/css?family=Roboto:400,300'rel='stylesheet'type

='text/css'>

@show

@yield('my_styles')

</head>

<body>

@include('partials.layout.navbar')

@include('partials.layout.errors')

<divclass="container">

<divclass="row">

<divclass="col-md-10col-md-offset-1">

@yield('content')

</div>

</div>

</div>

<!--Scripts-->

{!!Html::script('assets/js/jquery.js')!!}

{!!Html::script('assets/js/jquery.dataTables.js')!!}

{!!Html::script('assets/js/bootstrap.min.js')!!}

{!!Html::script('assets/js/datatable-bootstrap.js')!!}

<script>

$(document).ready(function(){

$('#MyTable').dataTable();

});

</script>

@yield('my_scripts')

</body>

</html>

Loscambiosmasnotoriosquepodemosobservaresqueel@yield('content')semetiodentrodeunacolumnaconunoffset,esodentrodeunafilaytododentrodeuncontenedor.Asinuestrocontenidonolovamosatenertodopegadoalaizquierdadenuestronavegador.

Nota:parapoderhacerestosoNnecesarioslosarchivosqueseincluyenconblade,sinolosagreganlatablaseveramassencillaperoestonoquieredecirquenovaafuncionar,yasoloescuestiondeestilo,siquierenobtenerlosarchivosdejamosloslinksacontinuacion

AnexoC.CRUDconLaravel

89

Page 90: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

paraquelosdescarguenylosguardendentrodelacarpetarespectiva,esdecirlosCSSenpublic/assets/css/ylosJSdentrodepublic/assets/js/:

EstilosparaelDataTable:datatable-bootstrap.css.

ArchivoJQuery:jquery.js.

ArchivoJQueryparaDataTable:jquery.dataTables.js.

ArchivoJQueryparaDataTabledebootstrap:datatable-bootstrap.js.

Nota:tambienlesinvitoaverelanexodeDataTableparamayorinformacion.

VistaIndex

Estavistaserefierealarchivoindex.blade.phpdentrodelacarpetaresources/views/pasteles/,aquivamosamostrarlatablayunbotonparacrearnuevospasteles.Ahorabienparaestodebemostenernuestropartialdelatabla,masadelantelovamosamostrarperoporelmomentoelarchivoindexquedariadelasiguienteforma:

@extends('app')

@section('content')

<aclass="btnbtn-successpull-right"href="{{url('/pasteles/create')}}"role="b

utton">Nuevopastel</a>

@include('pasteles.partials.table')

@endsection

Recuerdenquegraciasabladenuestrasvistasquedandetamañospequeñosmasfacilesdeentender,aquisoloestamosheredandolaplantillaappydefiniendolaseccioncontentconunlinkqueledaremosestilodebotonconlarutaparamostrarlavistadecrearpasteles,ademasdeimportarnuestratabla,elarchivopartiallodefiniremosahora.

Partials:tableyfields

Table

EstosarchivoslostrabajaremosenpartialsporcomodidadyporquesoncomponentesdeunsistemaWebquesuelenrepetirseconstantemente,empezaremosporeltable.

Primerorecordemosunpocodelpasado,ennuestrocontroladorenelmetodoindexdefinimosqueretornarialavistaindexjuntoconunavariablellamada$pastelesqueconteneriatodoslospastelesdelsistema,ahorabienesospasteleslosvamosavaciarenla

AnexoC.CRUDconLaravel

90

Page 91: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

tablapuessibiennoespecificamosqueesavariablevaallegaralpartialtablecomoloestamosincluyendoenelindextambiencompartelasvariablesquetengaindex,entonceselenviopuedeversedelasiguientemanera:

Entoncesvamosausarunforeachconblade,parallenarelcontenidodelatablaconlosatributosdelospasteles,dejandoelarchivoasi:

AnexoC.CRUDconLaravel

91

Page 92: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<h1class="text-primary">ControldePasteles</h1>

<tableclass="tabletable-bordered"id="MyTable">

<thead>

<tr>

<thclass="text-center">ID</th>

<thclass="text-center">Nombre</th>

<thclass="text-center">Sabor</th>

<thclass="text-center">Fecha</th>

<thclass="text-center">Acciones</th>

</tr>

</thead>

<tbody>

@foreach($pastelesas$pastel)

<tr>

<tdclass="text-center">{{$pastel->id}}</td>

<tdclass="text-center">{{$pastel->nombre}}</td>

<tdclass="text-center">{{$pastel->sabor}}</td>

<tdclass="text-center">{{$pastel->created_at}}</td>

{!!Form::open(['route'=>['pasteles.destroy',$pastel->id],'method'=>'DEL

ETE'])!!}

<tdclass="text-center">

<buttontype="submit"class="btnbtn-dangerbtn-xs">

<spanclass="glyphiconglyphicon-remove"aria-hidden="true"></span

>

</button>

<ahref="{{url('/pasteles/'.$pastel->id.'/edit')}}"class="btnbtn-i

nfobtn-xs">

<spanclass="glyphiconglyphicon-edit"aria-hidden="true"></span>

</a>

</td>

{!!Form::close()!!}

</tr>

@endforeach

</tbody>

<tfoot>

<tr>

<thclass="text-center">ID</th>

<thclass="text-center">Nombre</th>

<thclass="text-center">Sabor</th>

<thclass="text-center">Fecha</th>

<thclass="text-center">Acciones</th>

</tr>

</tfoot>

</table>

AnexoC.CRUDconLaravel

92

Page 93: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Laestructuradelatablalapuedenverenestelink,peroloimportanteestadentrodel<tbody>,endondeconBLADEvamosausarunforeachdiciendoqueparacadapasteldentrodelavariable$pastelesquellegodelcontroladorsevanavaciarsusdatosdentrodelafiladelatabla,primerovamosaagregarsuid,nombreyfechadecreacion,perosevaaagregarunacolumnadeaccionesquecontengadosbotones,unoparaeliminareseregistroyotroparaeditarlo,elbotondeeliminardebeserdetiposubmitparaenviarlapeticionDELETEyparaestoesqueseabreunformularioconlaclaseForm::deLaravel,paraqueasiquedesintaxismaslegible,agregamosloscamposnecesariosquesonlarutayelmetododelformulario;paraelbotondeeditbastaconunlink<a>queconlafuncionurl()deLaravellavamosadirigirconelIDdecadapastel.

Nota:Bootstrapnospermiteteneradisposicioniconosparaquelosbotonesdenuestrasaccionesseveanmasprofesionales,porlocualesloqueseagregaeltag<span>,paramasinformacioniralapaginaoficialdeBootstrap.

ConestodebemossercapacesdepoderverahoranuestratablacomounDataTable(encasodehaberagregadolonecesario)llenaconlainformaciondepasteles:

Fields

Ahoravamosacrearunpartialsconloscamposquevaarequerirnuestroproyecto,sibiensabemosesnecesariopediralusuarioelnombreysabordelpastel,perolafechadecreacionyultimaactualizacionsoncamposqueLaravelponeautomaticamentecuandoseejecutaelmetodosave()enelcontrolador,porlocualnuestropartialsolodeberatenerdoscamposdeentradayunbotonparaenviarlasolicitud.

Entoncesparaestearchivosolovamosaagregarcomosunombreloindicaloscamposdeentradaparaunpaste,dejandolodelasiguienteforma:

AnexoC.CRUDconLaravel

93

Page 94: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<divclass="form-group">

{!!Form::label('nombre','Nombre',['for'=>'nombre'])!!}

{!!Form::text('nombre',null,['class'=>'form-control','id'=>'nombre','pla

ceholder'=>'Escribeelnombredelpastel...'])!!}

</div>

<divclass="form-group">

{!!Form::label('sabor','Sabor',['for'=>'sabor'])!!}

<selectname="sabor"class="form-control">

<optionvalue=""disabledselected>Eligeunsabor...</option>

<optionvalue="chocolate">Chocolate</option>

<optionvalue="vainilla">Vainilla</option>

<optionvalue="cheesecake">Cheesecake</option>

</select>

</div>

SibienlaclaseForm::nosehaexplicadodetalladamentedejoellinkdeladocumentacionoficialdeLaravel,aunqueseencuentraensuversion4.2esdebidoaqueparalasversionesmasactualesnoseencuentraexplicada,perosiguesiendocompletamentecompatibleconLaravel5y5.1.

Conestepartialvamosapoderllamarloscamposdeentradaparacrearoeditarunpastel.

VistaCreate

Enestavistaaligualqueelindexquedaramuycorta:

@extends('app')

@section('content')

{!!Form::open(['route'=>'pasteles.store','method'=>'POST'])!!}

@include('pasteles.partials.fields')

<buttontype="submit"class="btnbtn-successbtn-block">Guardar</button>

{!!Form::close()!!}

@endsection

Extendemosdeltemplateapp,definimoselcontenidoabriendounformularioperocomosetratadeunalmacenamientoelmetodosevaatrabajarconstoreyPOST,dentrovamosaincluirelpartialdefieldsparatenerloscamposdetexto,elmenudeopcionesyunbotondetiposubmitparamandarlapeticion.

Deberiaquedarunresultadosimilaraeste:

AnexoC.CRUDconLaravel

94

Page 95: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

VistaEdit

AlteneryalistosnuestrosarchivosHTMLlavistadeeditsecreadelamismaformaqueladecreateconladiferenciadequeenvezdeabrirunformulariovamosaabrirunmodelo,esdeirvamosaabrirelobjetoqueseenviodelcontroladoralavistaparapodereditarloscampos,comoobservacionpodrannotarcuandoloejecutenenelnavegadorqueunselectnoseasignaautomaticamenteenvaloranterior,porelmomentovamosavercomoquedarialavista:

@extends('app')

@section('content')

<h4class="text-center">EditarPastel:{{$pastel->nombre}}</h4>

{!!Form::model($pastel,['route'=>['pasteles.update',$pastel],'method'=>'P

UT'])!!}

@include('pasteles.partials.fields')

<buttontype="submit"class="btnbtn-successbtn-block">Guardarcambios</butto

n>

{!!Form::close()!!}

@endsection

Aligualquelasdemasvistasseestaheredadndodeappyseagregauntituloparasaberquepastelseestaeditando,peroelForm::model()abrenuestravariable$pastelqueenviamosdesdeelcontroladorycreaunformulariollenoapartirdelosvaloresdelmodelo,claroqueestosoloparaloscamposquecoincidanconlosnombresdelosatributosdelmodelo.

Elresultadoseriaalgosimilaraesto:

AnexoC.CRUDconLaravel

95

Page 96: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

YconestoquedariannuestrasvistasdelsistematerminadasyelCRUDbasicodelosPastelesfinalizadotambien,paramasinformacionpuedenretomarloscapitulosdeestelibroparaanalizarlasdiferentesopcionesquetenemospararesolveresteejemplopuesestaessolounapropuesta,nounasoluciondefinitiva.

nota:Lasecciondeshownosehacontempladoparaesteanexoconunavista,disculpenlasmolestias.

AnexoC.CRUDconLaravel

96

Page 97: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

DataTableLosDataTablessonunplug-inparalalibreríaJQuerydeJavascript.Nospermitenunmayorcontrolsobreunelemento<table>deHTML.Algunasdesuscaracteristicasprincipalesson:

PaginaciónautomáticaBúsquedainstantáneaOrdenamientomulticolumnaSoportaunagrancantidaddedatosfuente.

DOM(ConvertirunelementoHTML<table>enunDataTable).Javascript(UnarreglodearreglosenJavascriptpuedesereldatasetdeunDataTable).AJAX(UnDataTablepuedeleerlosdatosdeunatabladeunjsonobtenidovíaAJAX,eljsonpuedeserservidomedianteunWebServiceomedianteunarchivo.txtquelocontenga).Procesamientodelladodelservidor(UnDataTablepuedesercreadomediantelaobtencióndedatosdelprocesamientodeunscriptenelladodelservidor,estescriptcomúnmentetendráinteracciónconlabasededatos).

HabilitartemasCSSparaelDataTablefácilmente.CrearuntemaTemaJQueryUITemaBootstrapTemaFoundation

Ampliavariedaddeextensiones.Altamenteinternacionalizable.Esopensource(CuentaconunalicenciaMIT).

¿CómousarDataTables?Paraocupardatablestenemosdosformas:

Descargarelcódigofuentedelosarchivosjsycssdedatatablesenelsiguientelink.OcuparunCDN

CSS//cdn.datatables.net/1.10.7/css/jquery.dataTables.min.cssJS//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js

UsarDataTabledescargandoelcódigofuente

AnexoD.ComponenteDatatable

97

Page 98: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

Antesquenadadebemostenerdescargadojquery,elcuálpodemosdescargardeaquí.UnavezquehemosdescargadolosarchivoscssyjsdeDataTablesdeestelinkdebemosextraerelcontenidoyubicarlosarchivosenlacarpetacssyjscorrespondientedentrodeldirectoriopublicdeLaravel.

Ejemplo:

public/

assets/

css/

datatable-bootstrap.css

js/

datatable-bootstrap.js

jquery.dataTables.js

jquery.js

LosiguienteseráhacerunareferenciadelosscriptyarchivoscssdentrodenuestrodocumentoHTML.

Losscriptlosubicaremosdentrodelaetiqueta<body>perohastaelfinaldelamisma.

<body>

<!--Contenido-->

<!--Scripts-->

{!!Html::script('assets/js/jquery.js')!!}

{!!Html::script('assets/js/jquery.dataTables.js')!!}

{!!Html::script('assets/js/bootstrap.min.js')!!}

{!!Html::script('assets/js/datatable-bootstrap.js')!!}

<script>

$(document).ready(function(){

$('#MyTable').dataTable();

});

</script>

</body>

Enelejemplodearribaestamosindicandoquelatablaconelid#MyTableseráunelementodetipodataTable.LaobtencióndedatoslahacemosmedianteelDOM.

Porotrolado,losarchivosparatemasdeldatatablelosubicaremosdentrodelaetiqueta<head>denuestrodocumentoHTML.

<head>

<!--MásarchivosCSS-->

{!!Html::style('assets/css/datatable-bootstrap.css')!!}

</head>

AnexoD.ComponenteDatatable

98

Page 99: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

DeestaformahemosconseguidocrearnuestroprimerDataTable.

CrearunDataTableExistendiversasformasdellenarunDataTablecondatos,veremosalgunasdelasmásusadas.

OcupandoelDOM(etiqueta<table>)OcuparemosunatablaHTMLconunid="example",posteriormenteconvertiremoslatablaenunDataTablemedianteunscript.

HTMLdelatabla

ElcódigoJavascriptparaconvertirlatablaconid="example"enunDataTablees:

$(document).ready(function(){

$('#example').dataTable();

});

OcupandoundatasetenJavacriptUnarreglodearreglosenJavascriptpuedesereldatasetdeunDataTable.

Javascriptdeldataset

Unavezdefinidoeldatasetbastaráconejecutarlasiguientefunciónparacrearunatableenundivconid="demo"ennuestroHTML.

AnexoD.ComponenteDatatable

99

Page 100: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

$(document).ready(function(){

$('#demo').html('<tablecellpadding="0"cellspacing="0"border="0"class="display

"id="example"></table>');

$('#example').dataTable({

"data":dataSet,

"columns":[

{"title":"Engine"},

{"title":"Browser"},

{"title":"Platform"},

{"title":"Version","class":"center"},

{"title":"Grade","class":"center"}

]

});

});

ElcódigoHTMLeselsiguiente:

<html>

<head>

</head>

<body>

<divid="demo">

</div>

</body>

</html>

OcupandoAJAXUnDataTablepuedeleerlosdatosdeunatabladeunjsonobtenidovíaAJAX,eljsonpuedeserservidomedianteunWebServiceomedianteunjson.txtquelocontenga.

ElarchivoJSON

ElcódigoJavascriptparalacreacióndeDataTableocupandoeljson.

$(document).ready(function(){

$('#example').dataTable({

"ajax":'json.txt'

});

});

ElarchivoHTMLcontieneunatablaconunid="example".

AnexoD.ComponenteDatatable

100

Page 101: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

<tableid="example"class="display"cellspacing="0"width="100%">

<thead>

<tr>

<th>Name</th>

<th>Position</th>

<th>Office</th>

<th>Extn.</th>

<th>Startdate</th>

<th>Salary</th>

</tr>

</thead>

<tfoot>

<tr>

<th>Name</th>

<th>Position</th>

<th>Office</th>

<th>Extn.</th>

<th>Startdate</th>

<th>Salary</th>

</tr>

</tfoot>

</table>

InternacionalizarundataTableEsposiblecambiarelidiomadelasetiquetasdeundatatablesibajamoselarchivodelatraducciónenelsiguientelink.

ParaocuparlotenemosquehacerreferenciaenlafuncióndelacreacióndelDataTable:

<scripttype="text/javascript"src="jquery.dataTables.js"></script>

<scripttype="text/javascript">

$(document).ready(function(){

$('#example').dataTable({

"language":{

"url":"dataTables.spanish.lang"

}

});

});

</script>

FiltrardatosdeunDataTable

AnexoD.ComponenteDatatable

101

Page 102: Table of Contentswebtech.cubava.cu/files/2019/02/0175-libro-laravel... · Anexo C. CRUD con Laravel Anexo D. Componente Datatable 2. ... Incluye un ORM: A diferencia de CodeIgniter,

PodemosocuparelcampodetextodebúsquedadelDataTableybuscarbajodiferentescríteriosseparandoporunespacioenblanco.

Ejemplo:

ParabuscarunadministradorcuyonombreempiececonlaletraOysuteléfonoseaextensión228,podemosponeradministradorO228

AnexoD.ComponenteDatatable

102