[Laravel] Werken met 2 databases binnen 1 project

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 13:27
Excuses voor mijn mogelijk verwarrende verhaal :P

Voor een projectje waar ik Laravel voor willen gaan gebruiken is het de bedoeling dat er per klant een database komt. Vanuit het loginscherm wordt er in de gebruikers tabel van de hoofddatabase een controle uitgevoerd en wordt de juiste klant database gezocht waaruit verderop de gegevens moeten komen.

In de voorbeelden van Laracast gaat het in principe om het gebruik van 1 database waarbij je direct verbinding hebt. Maar ik wil dus eerst de ene database raadplegen en op basis van dat resultaat de 2e connectie opzetten maar op zo'n manier dat er voor de rest van de werking gedaan kan worden alsof dat de "main" connectie is zonder dat ik bij elke query of get moet specificeren welke verbinding er gebruikt moet worden.

De users en password_reset tabellen worden dus in een aparte database gezet (bijv master) en het is de bedoeling dat bij de users dan nog wat info komt over welke database die gebruiker toegang tot moet hebben. Met die gegevens moet dus binnen het framework een nieuwe verbinding gelegd worden voor de rest van de werking. In config/database.php kan je wel allerlei connecties neerzetten, maar ik wil dus niet alle connecties hardcoded erin hebben. Dus waar kan ik dan het beste die connectie in 1x zetten zonder dat ik bijv in ieder model of controller de Config bijv aan moet passen.

=======================

Daarnaast kan ik nog niet helemaal vinden waar je nou zeer algemene functies het beste kan plaatsen en hoe te gebruiken. Verder vind ik nog wel dat het net iets te vrij is nog. Als voorbeeld:
- Zeg de url is garage.nl/auto/rood
- Dan heb je in de web een route die zegt autocontroller->get_by_color()
- Die controller kan op zijn beurt het model auto::find aanroepen of auto::where('color','rood') en de resultaten doorgooien naar een view.

Maar bij die laatste wrikt de schoen een beetje. Wat ik een beetje gewend ben is dat een class bij mij toegang geeft tot een tabel bijvoorbeeld. Dus een class auto geeft 1 of meerdere auto's terug. Maar alle functionaliteit, alle soort "uitzoekdingen" horen binnen die class, in laravel dus Model. En dus niet in de Controller.
Alleen, wat voor dingen doe je dan wel in de Controller. Ga je daar dan hele algemene functions plaatsen gerelateerd aan? Stel je wilt op basis van een geboortedatum een leeftijd berekenen en daar heb je een functie voor. Ga je die dan bijv in de UserController plaatsen? Stel dat je nog een tabel hebt als je het bijvoorbeeld over kinderen zou hebben waar je ook een leeftijd voor wilt vastleggen, dan ga je niet binnen een KindController diezelfde functie aanleggen. En om de leeftijd op te halen vind ik het weer onlogisch om te zeggen van $kind_leeftijd = UserController->get_age();.

Dus waar plaats je in Laravel in de structuur de functies die je normaalgesproken in bijv een lib zou zetten. Wat is wijsheid :)

Alle reacties


Acties:
  • +1 Henk 'm!

  • Khallouki
  • Registratie: Oktober 2006
  • Laatst online: 06-10 20:32
Waarom zet je niet gewoon losse omgevingen op?
Is het omdat je 1 url wilt communiceren richting je klanten?

Ik zou meer losse (sub)domeinen communiceren die elk zijn eigen omgeving heeft.

Zorg er alleen voor dat je je deployments automatiseert voor je verschillende omgevingen.

Acties:
  • 0 Henk 'm!

  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 13:27
Khallouki schreef op donderdag 19 april 2018 @ 15:15:
Waarom zet je niet gewoon losse omgevingen op?
Is het omdat je 1 url wilt communiceren richting je klanten?

Ik zou meer losse (sub)domeinen communiceren die elk zijn eigen omgeving heeft.

Zorg er alleen voor dat je je deployments automatiseert voor je verschillende omgevingen.
De bedoeling is om 1 omgeving te maken waaronder meerdere klanten vallen. Dus als we het garagevoorbeeld zouden gebruiken, heeft iedere garage zijn eigen database met eigen reparaties, eigen occasions. Maar ze maken op de frontend wel gebruik van dezelfde functionaliteit. Het zou dan ook meer de tool dan een echte website moeten zijn zeg maar. Want iedere garage heeft gewoon zijn eigen website. In the end is er 1 tool. Door middel van een EAV en wat slimme andere dingen wil ik zeg maar nog wel iedere gebruiker met elke database bij wijze van ondersteunen. Dus als een garage een veldje meer nodig zou hebben moet dat geen probleem zijn, zowel in de backend als frontend.

Ik kan er wel voor kiezen om in de connections alle verbindingen aan te leggen en die via de master zeg maar te "linken". Maar dan nog wil ik niet overal die verbinding moeten meegeven als het ff kan. Of de verbinding moeten aangeven.

[ Voor 22% gewijzigd door orange.x op 19-04-2018 15:32 ]


Acties:
  • 0 Henk 'm!

  • Iva Wonderbush
  • Registratie: December 2016
  • Laatst online: 06-10 07:57
Een leuke. Laravel gebruikt de APP_ENV variable om de .env bestand te bepalen, als je die kan setten voordat je Laravel omgeving bereikt wordt (met Apache zou dit makkelijk kunnen) zou .env.<APP_ENV> geladen worden. Van daar uit gaat alles in zijn normale werking (tenzij je de environment variables cached, dan is het wat lastiger).

[ Voor 10% gewijzigd door Iva Wonderbush op 19-04-2018 15:37 ]


Acties:
  • 0 Henk 'm!

  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 13:27
Iva Wonderbush schreef op donderdag 19 april 2018 @ 15:35:
Een leuke. Laravel gebruikt de APP_ENV variable om de .env bestand te bepalen, als je die kan setten voordat je Laravel omgeving bereikt wordt (met Apache zou dit makkelijk kunnen) zou .env.<APP_ENV> geladen worden. Van daar uit gaat alles in zijn normale werking (tenzij je de environment variables cached, dan is het wat lastiger).
De connectie naar de master wordt nu ook in de .env gemaakt. Maar ik zou bij een succesvolle login dus dan kunnen verwijzen naar een andere .env bedoel je? En dan fysiek voor iedere klant een .env maken en naar gelang aanroepen?

Stel dat ik wel er voor kies om de databases hardcoded in database.php te zetten (zovaak hoeft dat niet te wijzigen in dat opzicht). De users tabel krijgt dan een extra koppeling die ik ga gebruiken om de juiste database te selecteren. Sofar so good.

Maar hoe zorg ik er dan voor dat dus vanaf dat moment er voor alle controllers en mn querybuilder de juiste db geselecteerd is?
DB::setDefaultConnection('klant_1'); ?

Acties:
  • 0 Henk 'm!

  • Iva Wonderbush
  • Registratie: December 2016
  • Laatst online: 06-10 07:57
Nee, je zou met Apache de APP_ENV kunnen setten op basis van request afkomst, deze wordt automatisch doorgespeeld naar Laravel die het oppakt en gebruikt om de .env bestand te zoeken die erbij hoort.

Dus stel ik kom vanaf de IP 1.0.0.1, je set APP_ENV als "tweaker" in, zal Laravel dus .env.tweaker proberen te openen.

Je zal per klant dus een .env bestand moeten aanmaken en de database gegevens wijzigen. Zo hoef je helemaal niks in je code aan te passen.

Acties:
  • 0 Henk 'm!

  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 13:27
Iva Wonderbush schreef op donderdag 19 april 2018 @ 16:23:
Nee, je zou met Apache de APP_ENV kunnen setten op basis van request afkomst, deze wordt automatisch doorgespeeld naar Laravel die het oppakt en gebruikt om de .env bestand te zoeken die erbij hoort.

Dus stel ik kom vanaf de IP 1.0.0.1, je set APP_ENV als "tweaker" in, zal Laravel dus .env.tweaker proberen te openen.

Je zal per klant dus een .env bestand moeten aanmaken en de database gegevens wijzigen. Zo hoef je helemaal niks in je code aan te passen.
Ik begrijp wat je voorstelt, alleen zal dat denk ik niet goed werken in dit geval. Ik zoek ook nog even verder :)

@Iva Wonderbush heb je misschien wel een simpele uitleg van welke zaken je nu wel en niet in je controller regelt en in je model? Je kan in theorie in je controller functie die je aanroept 80 regels code gooien voor het ophalen van allerlei data en dat gaan verwerken terplekke... Maar "hoort" dat? Of is het meer dat je vanuit je controller functie weer andere functies aanroept vanuit een model / andere controllers? Je wilt uiteindelijk geen controller bestand met 3000 regels code, is mijn visie..

[ Voor 25% gewijzigd door orange.x op 19-04-2018 16:59 ]


Acties:
  • 0 Henk 'm!

  • Iva Wonderbush
  • Registratie: December 2016
  • Laatst online: 06-10 07:57
In theorie zou je ook alles in je blade template kunnen gooien :P

Laravel gebruikt als "basis" MVC, dus als ik jou was zou ik mij daar in gaan verdiepen wil je je code netjes houden en de "regels" volgen.

Acties:
  • 0 Henk 'm!

  • _Moe_
  • Registratie: Mei 2006
  • Laatst online: 04-08 14:45
@orange.x De opbouw van een Query kan je doen waar je wilt, zowel in de Controllers als in de Models. Het is juist wat je wilt. Enkel een tip, zorg ervoor dat je consistent te werk gaat.

Waarom wil je werken met verschillende databases?
Waarom zou je niet met verschillende omgevingen willen werken?

RTFM!


Acties:
  • +3 Henk 'm!

  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 11:34
Je kan per model aangeven welke connectie hij gebruikt ook. Dus bijv. je Users tabel kan je op 'default' zetten, maar Customers op de 'client'. En dan kan je in een ServiceProvider de client connectie invullen met gegevens. Dan is je client connectie dus dynamisch.
_Moe_ schreef op vrijdag 20 april 2018 @ 09:19:
@orange.x [..]

Waarom wil je werken met verschillende databases?
Waarom zou je niet met verschillende omgevingen willen werken?
Of waarom zet je niet alles in 1 database maar hou je een garage_id of website_id bij. Eventueel met een global scope zodat je makkelijk je queries beperkt tot die database.

Meerdere databases op 1 omgeving is lastiger met onderhoud, want bijv. je migraties moeten op elke database doorgevoerd worden tegelijk. Dat is bij 3 databases niet zo erg, maar bij 500 kan dit een stuk langer duren.

Losse omgevingen kan ook, maar dan moet je je deployments goed inrichten en het makkelijk maken om nieuwe sites toe te voegen. Wel makkelijker op te splitsen en losse versies te testen op een aantal websites, ipv alles tegelijk.

Acties:
  • 0 Henk 'm!

  • dvdheiden
  • Registratie: Maart 2006
  • Laatst online: 12:46
Lees dit maar eens door, vrij uitgebreide omschrijving van het principe:
https://hackernoon.com/th...lti-database-779ea4592783

Acties:
  • 0 Henk 'm!

  • Groax
  • Registratie: Oktober 2012
  • Laatst online: 02-10 11:33
Barryvdh schreef op vrijdag 20 april 2018 @ 09:28:

Of waarom zet je niet alles in 1 database maar hou je een garage_id of website_id bij. Eventueel met een global scope zodat je makkelijk je queries beperkt tot die database.

Meerdere databases op 1 omgeving is lastiger met onderhoud, want bijv. je migraties moeten op elke database doorgevoerd worden tegelijk. Dat is bij 3 databases niet zo erg, maar bij 500 kan dit een stuk langer duren.
ik gebruik laravel regelmatig en meerdere DB's is leuk maar is dit echt nodig?? Je kan ook naar Lumen kijken en een API call maken. heb je toch je meerdere databases maar 2 losse applicaties die nauw samen werken.

Maar ik raad aan om gewoon 1 DB te bouwen. Puur voor onderhoud. Geloof mij.. dit wordt anders een pain in the ass

Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Ik weet niet of de klanten zelf ook bij de code kunnen, maar als dat niet het geval is, dan zet je toch een sessie-variabele, waarmee je het betreffende Eloquent-model aanroept van de klant? In het Eloquent-model defineer je dan de connectie dat gebruikt dient te worden. Je krijgt dan dus een dynamische class, basicly.

EDIT:
Al denk ik dat de oplossing van @Barryvdh de meest schone is.

[ Voor 22% gewijzigd door CH4OS op 20-04-2018 14:35 ]


Acties:
  • 0 Henk 'm!

  • NotAFarmer
  • Registratie: April 2018
  • Laatst online: 12-09 16:13
Ik voeg mij aan bij wat Barryvdh voorstelt, wij hebben voor onze applicaties ook per klant een "ingang_id".
Zo hebben we een applicatie, met een database en meerdere klanten.
Het "ingang_id" wordt dan leidend..

Acties:
  • 0 Henk 'm!

Verwijderd

orange.x schreef op donderdag 19 april 2018 @ 16:43:
[...]

Ik begrijp wat je voorstelt, alleen zal dat denk ik niet goed werken in dit geval. Ik zoek ook nog even verder :)

@Iva Wonderbush heb je misschien wel een simpele uitleg van welke zaken je nu wel en niet in je controller regelt en in je model? Je kan in theorie in je controller functie die je aanroept 80 regels code gooien voor het ophalen van allerlei data en dat gaan verwerken terplekke... Maar "hoort" dat? Of is het meer dat je vanuit je controller functie weer andere functies aanroept vanuit een model / andere controllers? Je wilt uiteindelijk geen controller bestand met 3000 regels code, is mijn visie..
Je haalt het op met je models en gaat ermee aan de slag in je controllers.

Ophalen en aan de slag ermee gaan in je controllers zal deels het werk doen van wat de models eigenlijk dan zouden moeten doen.

Acties:
  • 0 Henk 'm!

  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 13:27
dvdheiden schreef op vrijdag 20 april 2018 @ 09:32:
Lees dit maar eens door, vrij uitgebreide omschrijving van het principe:
https://hackernoon.com/th...lti-database-779ea4592783
Volgens mij moet ik hier wel mee uit de voeten kunnen!

@ de rest: Splitsing is wel een eis, maar zou goed moeten komen dus. Voor wat betreft de plaatsing van welke code waar ga ik wel een "regelset" aanleggen. Als zaken dus maar consistent zijn inderdaad en op logische plekken staan.

[ Voor 9% gewijzigd door orange.x op 23-04-2018 12:16 ]


Acties:
  • 0 Henk 'm!

  • PainkillA
  • Registratie: Augustus 2004
  • Laatst online: 26-08 19:26
waarom niet je applicatie draaiend op losse servers met losse database? De kern van de applicatie publiceer je als composer pakkage in elke site. Bij een nieuwe release update je de sites en word de database automatisch geüpdatet met migraties. Bij klant X draait dan bijv 1.2.3 en bij klant Y 2.3.0 van je core app.

Zaken customizen kan eenvoudig per klant door bepaalde services te decoraten of aliassen/vervangen. Daarnaast kan je dan per klant nog maatwerk erbij bouwen lokaal.
ik merk vaak data laravel gebruikers wat minder letter op architectuur. Waarom die SOLID code produceren door bijv repositories te gebruiken om je database laag te abstraheren? Dan worden je controllers veel kleiner, haal je die verantwoordelijkheid van je model weg waardoor je model zich alleen bezig hoeft te houden met domein logika. Daarnaast overal dependency injection gebruiken ipv facades en static calls waardoor je SOLID en dus veel flexibeler en erg belangrijk ook unit testbare code oplevert.
Pagina: 1