Making Laravel apps tenant aware using laravel-multitenancy

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody and welcome on this stream yeah the stream is a little bit informal so I haven't prepared too much I just want this to be natural if you have any questions at all just ask in the chat I really like if it's a little bit interactive so please send me all your questions and I'll just take a look at the chats every few minutes to see if there are anything interesting there now what I would like to know from from somebody of you is if the sound and the and the interview is correct can you see can you see everything can you hear me 1 2 3 tests 1 2 I hope somebody sound ok feely ok ok thanks you know again for further assist maybe I'll FaceTime you again in a in a bit good so we are going to talk a little bit about a package that I've made made called laravel multi-tenancy if you have any questions about this just let me know the chat if you have any questions about other things just ask it - this is like an informal thing like I've said now before I head into the talk I want to bring your attention to something that I've launched yesterday the laravel package training course and that course contains like basically everything that I know about about package building it's 4 hours of of content we cover a lot we say how you can build an agnostic package how you can build a larval package and we will source dive some spicy packages so I think there's something to learn from everybody reactions have been great until now and what I can also show you get your pen and paper ready I've got a coupon code especially for you dear streamers thank you for watching if you use that coupon code then you get a discount of $10 and this discount code is only available yeah today so if you want to make an advantage of this use this code today and I've also made that code valid for mail-coach so if people are interested in mail-coach just use that coupon code and you get a $10 discount as well so that was it for the commercial side let's talk at larval multi-tenancy yeah multi-tenancy has been this like big subject and to me it always seemed a little bit heavy and something that I really wanted to get into because yeah it's it seems just a little bit too difficult but for a recent project yeah I had to research the problem a little bit and yeah it was pure luck that Mohammad Sayeed the larval employee also just started some videos about multi-tenancy and his views on it and I I really like this is lightweight approach on it and I try to package that up and my package is even more lightweight than what Mohammad said the package is also yeah inspired by of course the videos that Mohammad made and through various conversations that I had with moment so let's take a first look at the tag line of the package and an opinionated multi-tenancy package for larva laps well what do we mean with an opinionated when I was looking around for like multi-tenancy packages I saw that most of the packages did a lot they try to solve all the problems that that are involved with multi-tenancy so what I did was they provided like at first thing they did was like provide a good system to switch from tenant to tenant so to keep like the current tenant somewhere in memory then they had some code for like what should be done when switching a tenant how is the database connection going to be switched how is a file system going to be switched and he had a lot of code and options for that and the third thing that respect Jews have is like some tooling yeah how do we run like an artisan command for or like how do we run migrations for all time and stuff like that and it was really heavy code and I didn't really like that so what what this package tries to do it is it will give you a simple way of tracking the current tenant but for switching between tens what should be done what configuration should be changed the package really doesn't care about it it just provides you an easy way to define what should happen when we switch the tenant and for like the tooling where other packages mostly have like commands for this is how you might create tenants this is how you do that for that tenant this is how you do that for all tenants our packages provides one command to make all existing tenants to make all existing artisan commands tenant aware so it's even though it is a heavy subject it is a very light package it can be used for strategies that need for applications that need one big database for all buttons it can also be used for projects where each 10 as its own database and that is what I will be demoing today so I said that I didn't prepare anything but I actually have a demo application already here and in this application yeah I already installed package a made a few light modifications so in composer Jason you see that we have laravel multi-tenancy you can see that I prepared this demo a while ago and still using def master here and I'm too afraid to switch to the stable release in this video but after the video I'll try that out and what we have here in the config directory is an extra file called multi-tenancy and these are basically all the options that that the data package provides so the the simple the way we kick off this template is how you can find a tenant and we use for that a tenant finder so jason has a question here how do you get phpstorm to show the installed version so that's here in comparison to Jason I think it's just the default in the latest PHP storm version so if you're on this version you should automatically get it I didn't do anything for that at all good back to the configuration file so we have a tenant finder here and this one defines which of your tenant is the active one for the 40 request let's take a look at that domain tenant finder it's actually a very simple class it has one method fight for the request we give it we give you the request and this class should give the back and the tenant let me show you that first it's also important to know I have got some databases here and I think it's called the land more to one I guess landlord database has a tenant table that has a row per tenant so a tenant is a name it has a domain and we'll use this - it has a separate database and I don't think that this is the right database because it is it is empty let's go to maybe the database config file and here you can define various connections right for your for your level application and what the package assumes if you use multiple databases is that you have a tenant connection and it has a you can use any database that you want but by default you should keep the database at no and we are going to dynamically change that the database name when switching tents I'll show you that in a bit we also have a landlords connection here and that landlord connection yeah that's just for the information that your application stores that is above your tenant some people also call it like the system database and we use empty landlord here multi-tenancy landlord let me see if I was in the right database I know it is larval empty land for it here so here it's empty landlord I can close this connection I guess I and here we have tenants so our first tenant lives on this domain the second tenant lives on that domain ok let's go back to phpstorm so we have multiple database connections here maybe back to the multi-tenancy config file so here we have our domain tenant find and here we use that tenant model and we just do a where domain and we give it a host object requests and the first tenant that we find will be made the active one now what happens when you make a when you make a tenant the active one well if you take a look in the config file again we have this option switch tenant tasks and by default there aren't any tasks in here because you as a package user should define what should happen when you switch a tenant but the package provides you want tasks to to get inspired and that is the switch tenant database tasks now let's what see what is in this task a task is actually a very simple class it implements the switch tenant tasks interface and you need to yeah implement two functions make current and forget current and make current is the interesting one will give you the tenant that will be made the current one and yeah you should change the configuration in a way that makes sense to you forget current that's that for requests that that make a tenant active but you actually want to switch to the landlord configuration again then you can do so now let's switch back to that switch database tasks and let's see what happens I what the implementation is form a current here for the switch tenant database tasks what we are going to do is we are going to set the tenant connection database name to the database name of the tenant so the gate database name here is just getting the attribute here and let's take a look here so that's laravel mt tenant 1 & 2 so let me open those connections as well what was it my my brain you forgot one felt empty tenant yeah larval empty tenant 1 and maybe also let's open larval empty tenant 2 you can see here that we have users database for the first end we have used the other base for the second tenant as well but here we have that database name defined so we are going to give that database name to set tenant connection database name and what we are going to do here is we are going to get the tenant database connection name so in the config file you can actually define the name of the tenant database connection name is just tenant and again we reference there this name of this database connection which is just tenant what are we going to do with a database connection name well if there is no such connection name yeah we just bail out but if there is one we are going to set the database name of that configuration so this variable we are going to set it to the database name that we provided and in this case it was a database name of the tenant and then we are going to purge the connection so this this statement will actually let laravel forget the connection and whenever the first query comes in again it will rebuild the connection and so we're using actually bye bye bye this we're using the database that is configured here that's how that works wait let me go back to the right thing maybe let's see it in action so let's go to the Welcome view I've already prepared to welcome view a little bit so normally it says here the word welcome but I've replaced it with the name of the current tenant so if I go back to the database to the landlord connection you can see here that the tenant also has a name is there something else I should say about this maybe here it feels a little bit strange maybe to get the current tenant out of the container this was just the easiest way for me to do so but you can also just use the the model itself tenant and get current here but that's a lot yeah that's that's another way of doing it but I don't like that that's a fully qualified class name here normally you wouldn't just fetch it in a few but somewhere else in your code probably in your controller now that I'm here you have several other methods here on on a tenant what you can do here also is chequered if there is a current tenant and let me also show you how you make a tenant current you can make a tenant current if you just have a model of that and you just call make current on it and then it becomes the current tenant but this happens mostly behind the scenes I'll talk about this later let's put this back in place let me show you something else on my terminal so I've actually prepared to fillet a little bit you can actually point different URLs to the same application you can see here that I have the tenant one domain is also pointing to this demo application and the tenant two domains also are going to this application I think you can just add a link with FLL link and just add something here I think if you just do denim tree here yes symbolic link then we have like but I I used this tree I should have used tenantry but you can see her that now HTTP test tree top test also points to this application that's that's how that works okay so I've bled a lot let's see if this is actually if this actually works so I want to see that if I go to this domain I use data database if I go to that domain I use that database alright let's write out so it's tenant one test oh maybe you saw me autocomplete here and then it's c4 laravel this is actually also one of one of the better alternatives for multi-tenancy if you're interested in our package I also suggest that you take a look at this one they are actually a couple of other interesting ones I think I have mentioned those somewhere I think in the github repo with alternatives so this if you don't like my package or if you just want to check out what others have done just take a look at the others one as well and just pick the one that that is best for you this is something that I do with multiple of our packages I am NOT saying that our package is the best it's just the one that works best for me and I always try to give the other ones a little bit of attention as well ok but I want to do something else I want to show you that our package actually works so I'm going to tenant one dot or maybe watch this to tend to the test you can see here that we're at 10:02 so we display like the right name here let me check if there are any questions meanwhile and I don't see any questions here okay let's go further and if I go to tenant one here then we use the tenant one database so let's go to ten - and maybe let's register now something because I just used the default laravel scaffolding here and I haven't changed anything about that code at all but it should be tenant aware now so maybe I do user user of tenant - I just registered myself here yeah use a strong password register here and I'm now logged in here as a user of ten - and if I go to the database and if I go to the first tenant connection there's no user here but you can see here that it is in the database of ten and two so that's how that works I see a question coming from Nuno do you have this package running in production at the moment if yes what are the paints that you found so far well it is built in in a project that I'm currently building but that project has I think a development time of I kid you not two years or something so it isn't I haven't used it in production yet but we're using it in yeah something very big and [Music] I've hit some pain points while testing but I've all polished them out while I before tagging 1.0 so yeah hey I love the author - section in the readme yeah I love that too I wish that more people who do that because I think I in open source it's not really competition and trying to get us money much eyeballs but I want people if they choose like a package of ours I want them to have considered the alternatives as well and maybe there's an alternative that's better maybe they don't want to use a lightweight multi-tenancy package maybe they want to have like something with all batteries included so yeah I think listing alternative is an open-source is a good thing to do will this be able to run on paper I guess so because there's really nothing specific here we just have a way of tracking the current tenant and we we keep rebind that in the service container and what should be done when switching a a tenant you can just define that just I think if your own vapor just create your own tasks that work on vapor for you use it with mail-coach please well on the roadmap of male coach we actually have multi-tenancy on the way also drip campaigns and will likely work on that somewhere in the summer ok let's take a look at something else maybe how we run my creations that's also a fun thing to do so you've seen that there are three databases here and there's one land ports database and it has its own migrations so we create like the tenants table you can see here that the tenants databases they all eat they also have their own my creations and our picture or our package doesn't assume I assume that you are probably going to have all the databases of the ten is the same that in ten a database one probably you won't have an extra table here you could do it but I think I think it's not common I think the tenant databases I use the same scheme now let's see how we can run those migrations so maybe it's fun if I just I just remove remove it all so you can see that actually work so I always like to see to to let people see practical things and make them feel like this is working let's go to here and let's go to our database directory here and here you can see that we have in our migrations subdirectory landlords now I think that using or changing the tenant databases is what you'll commonly do I think that the longtail or database will be the more stable one so I try to have like the tenant migrations like the default one so you can still use make migration and it will become a tenant migration and the landlord is more something special than you should if you make a migration move it to the landlord migration now how do you run those landlord migrations well you can actually use the migrate command here and migrate command accepts a a part two where the migrations are and you just should just specify the directory it doesn't have to be left or - you can store them in any directory you want you should also specify the connection name you want to run them against now this is something that larval named wrong I think this is not the database name this is the connection name that is in the in the config file so this one does not reference database but it references the landlord maybe I'll create an issue for that on on the larval repo so if I run this then you can see that there are migrations ran and you can see the tables coming back here but now how do we run the migrations for all the tenants we can't just use migrate here because yeah that how does it know for which tenant it should do that it should really do that for all tenants and the package ships with a command called Tenon's artisan and what this command will do is it accepts another artist and command and it will loop over all the tens it will make each of them current and run the command you pass it to them and we even and if the command loops over it we also give some outputs that you know for which ten Atari you're going to do something it will also give the output of the command you give it so let's try it out pepper and that didn't work all done ah yeah I didn't I don't have any tenants defined right how can I fill this can I just see this also nothing to migrate but did it see it we have no tents no you know what I just it's like that maybe we have some seed outta here now we don't have some seed data so does anybody know how to see it also here I guess that this is wrong otherwise I'll just manually manipulated but Papa Papa Papa no reaction so I'm just going to add the Dennis myself again oh not a table what am i doing just row here this is tenant one this is for the tenant one the tests and we have here the larval empty tenant one here that's that and then let's duplicate that row and this is ten to ten and two and for this one you need to use the second database and that's it I guess yeah maybe I should should have dumped that from Francisco thanks for that but I guess that this should should work as well okay let's go to the project again and let's try the tenants command again yeah and now we might create it you can see here that we looked over it we set that talent as the current one and we read the my creations and with any luck we have some tables here again so that's how how that works so it's pretty cool that you can make any command that isn't tenant where you can actually make it thinner to where now there's one more thing that I want to show you and that is the tent where queues and for that I think I got something prepped here in web yeah ok so let me also flush ready so that there is nothing in the horizon queues if you're interested in that command flush Redis that's it this just nuking all of ready so that there isn't anything in there okay so for jobs imagine that you have a tenant active there's a tenant that has been made current and request and in that request you dispatch job now it is I think it would be nice if inside that job the tenant that was the current one when the job was dispatched is also active in the tenant as well and that's something yeah that that we that we provide in the package as well so if I go to multi-tenancy we have another option here queues are telling to where by default there are actually some other ways to mark jobs as a stand-in to wear but I'm not diving into into that now go take a look in the documentation to see how that works let's just use the default F option that queues are tend to wear by default so I have here if I visit just the route here I'm going to dispatch the test job and what I'm going to do here is I'm going to get the current tenant and I'm just going to lock the name of the current tenant here and I'm going to say which database that were using in this job so let's try that out so I'm going to tale the lock I'm going to maybe split vertically here and I'm going to start horizon so horizon started successfully now let's just start a job by making just a request to the second tenet maybe I'm not logged in anymore but with any luck this should fire a job I know it's only on the welcome view it's not on the login right it's here so yeah job is dispatched I am Cassie here hello from 10 a.m. to 10 - was the active one in this job and yet if I go to tenant one then here we say hello from tenant one so tenant one was active in the job and this was the active database in the job so that's how that works ok that's how you can use the package I'm also going to say yeah the package work so we're going to source that the package but let me see if there are any questions now what is your idea about sickle Pro so I think you mean the tool sickle Pro I think it's it it was fine but I think it's a year ago it wasn't maintained very well and then I bought a table plus license which is actually maintained and I've stick to it ever since because yeah it's it's a nice UI and it works for me very well yeah I really like the views and yeah the the general layout of of how it works I liked having the colors here and such right yeah I've switched and I haven't looked back because it just works perfectly for me then if I get that right then an artisan does the job for every tenth can you specify a tenon to run a single command only for that one or do you have the current tenant one in CLI as well well let's already source that a bit spoiling we have an option to run it for the current tenant let's just go to the package maybe you'll have multi-tenancy so this is the source code to the package itself you can see here that we have one command that tells Arsenal command and you can see here that we also accept some tenant IDs here so what are we going to do when this command is handled we are going to start a query for a tenant we're first going to if you didn't provide an artisan command you will actually ask which artisan community you want to run then we are if there is a tenant ID set or if there are multiple ID sets we are going to add a we're close to it so we only going to run it for those tenant IDs then we are going to loop over them with course cursor which is a very efficient way of looping above of looping large datasets and for each of those stands we are going to run that artisan command that you gave us so what we are going to do is we are going to outputs some some light so you know which tenant that we're now working with we are going to make that ten of the current one and with making the tenth current one we are going to execute all the tasks that you defined here so here in the demo via switch database tasks here and then we're just going to call that command and that's basically all there is to it so I hope that answered that questions now you what about jobs that run for the landlord should fail to stable also beyond the landlord migrations I guess it does if there isn't any tenant the current one when you dispatch a job then no tenant will be made the current one inside that job so if you're on the landlord connection or if you are in a request for the landlord then no tenant will have been made active and all jobs will also run against the the landlord one question here so multi tenant needs a centralized database to manage tens no not at all you could use this perfectly for a with a single database where you maybe have some tables where you maybe have four users you have tenant ID here in the tenant and the tenants live inside this this database as well the package makes no assumption for that at all you've seen that we've switched databases because in our the demo application if I have it here we had that we had that specific task here to switch the databases but if you don't have this task yeah you'll basically just use just use one database this may be also good to see that we papa papa let me let me show you that in the package itself this one we actually have a tenant model here and you can see here that we have uses landlord connection here and that's just setting like the connection name of this and if you only have like one connection what you should do is in your configuration file you can just set like the Papa Papa yeah the tenant database connection name to null and your landlord database kinase connection - name - no and then we'll just use the default database connection which is I think MySQL for both the tenants and the nd landlord and then you're basically working with one database is there also a separate cache for the tenant and the landlord well again by default the package doesn't do anything for that if you want to do that you should create a task and add it here now it's a nice coincidence that the package has a task which isn't used by default for switching cache let me show you that so here are the two tasks that package ships with and they are more for inspirational uses so because there are multiple ways of switching databases maybe you want to use a different port or something like that but this shows you just a way that you can switch database and we also have that for the cache for the cache it works similarly we if for this task the cache should be different so if you know if the if this tenant should be made a current one we are just going to change the cash prefix to a certain cash base I think the cash base where is it yeah it's just standard score I default with the tenant ID and we are just going to dynamically change the cash confit and larvell actually let me go to the database add to the to the real demo application it actually has an option for memory based caches to just define a prefix and then you'll have separate separate cache instances maybe I should show you the tests for this one so it's it's also clear let's go to tasks prefix task test so this test it probably says it will separate the cash for each tenant and Papa cannot open bf like that this does this test passes so we are going to push push something in the cash for the key original value we are going to make it another current one we are going to put key again and here with the tenant value we're going to do the same for another tenant then we are going to make the first set of the current one and if we then get key then we have the tenant value if you make in other current tenant the current one we get another value and if we forget the current tenant then we get the original value so that is that is how that works before diving into more source code let's just see if there are any questions any other changes in control or mod file no not really the form models you should let me go to this one for your models the only thing you need to do is to apply the user's landlord connection or uses tenant connection trait and they ascetical next name that we have in the config file that's the only thing that you need to do to your models and your controls you don't need to do anything there at all so the cache service is shared and you act on the cache to set with the right prefix yes the task that ships with the package does just that but if you want to do it in some other way just create your own task and creating a task is very easy let's just do it in the demo application here let me just create like a support support directory let's create a class in here switch or maybe I'm going to prepare cache prepare to cache tasks or something like that this one should implement I guess it's I don't know how the interface is named switch tenant tasks okay so implements switch denim task add method stubs yeah and if this tenant should be made current one yeah just change the configuration of of your cache in such a way that makes sense to you what could you do here yeah maybe if you use the database driver you could let that task just change like the table name or something maybe you want to use different tables / / cash you can do whatever you want this is like the uh opinionated part of the package the package doesn't know what you want just it allows you to easily define what should be done when switching a tenant and what advantages do you think there are between one or multiple databases from a programming perspective I think this is my personal thoughts on this is that I think for the maturity of like sauce like applications like for instance the type of oh dear or maybe Forge I think just having like a single database and just using a foreign key in each one of the tables to scope pertinent this is just good enough I think it's a multiple database to me only makes sense for like very big applications so like the one I'm building now it has like it has hundreds of tables the relations go pretty deep and you could solve it with like just scoping queries and such but it is so cumbersome then it actually makes sense to have like the other basis per tenant it really depends a little bit but I do think that like in the vast majority of cases like a single database is enough if you want to know more on that you should see the Larkin talk by Tom slick I think I've mentioned his talk in the introduction of my package and he tells a lot more about the present accounts about that he is professional I'm just just doing whatever I think is right or feels right how do you handle file uploads from different tenants well what I would do probably is if you want to have like different yeah storages per disk I would probably have like a tenant disk here and I would create like a task that just changes the route of the disk per tenant and you can yeah I guess you can do that with with s3 as well just if you're using a stream and you want to have your reports pretend just create a task switch pocket or something and dynamically change the bucket property let's see how do I set permission cash for each tent yeah it's been a while since I use spazzy permission cache myself but I guess it is just changing dynamically the cache config file just created tasks for that and you're dumb an idea would be called switch view team yeah sure go ahead do that the package doesn't care I'm not going to include it in the package because I want to be it's very light and I don't know who needs that but if you need it just go ahead and create a switch view team I tried this package and it doesn't work for PHP 7.3 yeah we only support the latest version we have the luxury of getting to use the latest version on our projects so for us it really doesn't make sense create supporting older PHP versions we just want to use the latest version of the language we create those packages mainly for ourselves and we want like the maintainence burden to be very easy and we don't want to think about all PHP versions that's why we normally just really don't care about all the PHP versions if you needed something for an old PHP version check if there is like an old version of our package maybe it's stable and if there is an old version yeah then I guess you should fork the package and invest your time to add compatibility with it just doesn't make sense for me to invest my time in it because yeah I don't need compatibility with older version that's that's why ok no other questions so I'm going to highlight one more thing in the code and that means basically yeah how do we actually yes which switch tasks so let me go to this is the demo application maybe you should go to the service provider of the package because this is where it all starts right so what are we going to do here in this package here is where it gets interesting so if you don't know what the service provider is just by our laravel package training course I'll tell I'll tell you their butt joke is I don't value here it's just the entry point of a catch larvae we'll call this when yeah when when larval boots it will go over to every service provider and I guess it first calls register on all service providers and then it calls boot on all service providers so what are we going to do here we are going to do some general stuff for the package but here is where it gets interesting we are going to register the tenant finder and the tenant finder that was that class that finds the tenant for the current request so we give you the request you should give us back the tenant that should be should be made active we are going to register that task collection so that is that those tasks here those will be instantiated and then here's where it gets interesting then we will configure the requests so in configure request what are you going to do we are going to call if we're not running in the console but if you have an actual web request we are going to determine the current tenant so we are going to take a look in the config file which is the current tenant finder we are going to instantiate that and then we are going to call that find for requests method which maybe gives us a tenant back and if it gives us the tenant back we will actually make that tenant the current one that is basically all that is done now let's take a look in the tenant model what we do to make a tenant current blank out here is here models tenant so make make tenant current what is happening here we are going to call an action class an action class that's also basically something that is defined in the configuration file here you have several actions that this package can make and this is basically to make the behavior even more configurable mostly these actions they do what they need to do but if you want to make some changes low-level you can override these actions as well but let me go back to the tenant so we are going to get that action class and we are going to call execute on it and we give it the dis which is the tenant that we are making the current one and what we are going to do here is actually very simple we are going to raise an event so that you add other parts of your application now hey we are going to switch tenant then we are going to perform the tasks to make the tenant current and that's basically going over the tasks collection and tasks collection that is a class that is basically a wrapper to all tasks that are defined here and we are going to call make current on each of those tasks and those make turn current functions you've already seen those in the switch database 10 tasks here we are going to switch the database name of the current tenant connection in the cache tasks we were going to change the prefix of the tasks so that is what is being done here that is perform tasks made the tenant current and then we are going to bind the current tenant and that's basically just putting the tenant instance in the in the container and we use the tenant container key in the config file and by default I guess its current tenant yeah its current tenant and that's yeah how in the Welcome view here that works so this is because we've bind current tenants in the indie container let's go back to the package switch where were we make ten transaction yeah so perform tasks to make the tenth current and bite the current tenant then we fire of little events that the rest of your application knows hey there is another current tenant and that is basically it cool maybe one last thing that I gonna show you is how we make the queue stand to where because that's also a nice thing and that's being set up in the service provider and that's actually a trick that I learned from Mohammad Yunus videos so here after we've made the after we configure to request so we determine the current tenant we are going to configure the queue and that's also being done by an action that will execute make tenant current aware and we're going to do something when jobs are being cute so when you're going to dispatch a job we're also going to do something when a job is being processed what are we going to do when a job is being cute well we are going to say we are going to register a callable to the larva queue and larva will actually execute this whenever a job is dispatched and you can actually inject extra data in every job this way and what are we going to inject in the extra job if this job is tending to where and that is the case when you when the option is true here which option cubes are tend to wear by default and in most cases this will return true and if there is a current tenant then we will say if you make a job add this to the payload tenant ID and give it the current the idea of the current tenant so that's being done when a job gets dispatched when a job is being processed so when it gets pulled from the queue ready to be handled we are going to do something we are going to listen for a certain event jump processing then we are going to take a look at hey this job in that payload is there a tenant ID that we just said if there is no we are not going to do anything but if there is a tenant active we are going to find the current tenant for that ID and we are going to make it the current tenant so we are going to again make to make current that's just executing this action we are going to perform those tasks we are going to bind it as a current tenant and that is really all there is to to the package I think it's really lightweight it's it doesn't get in the way I also think that if the package we if you want to customize the package or you don't want to be dependent on the package I think you could just copy the code into your application and it's simple enough to understand to modify a little bit let's head back to Safari so yeah I've source dived the entire package with you the documentation yeah explains everything that I've said and in some places in in more detail then then I've said if you liked this source dive the package training that we've launched also contains a few other source dives as well so if you if you want to see me explain some some other things yeah you could consider buying this course one of my favorite videos in this course actually a 90 minute long video where I create a package from scratch and I really had a lot of fun creating this one I just record hit record and didn't cut anything so I explain how I think you can see me make mistakes because I make mistakes as well now if you like if you want to buy this course remember use this coupon code which is only valid for today thank you for watching let's head back to multi-tenancy and the last thing that I'm going to do is yeah see if there are any questions about this package or anything else and otherwise we'll be done let's see here I'm watching two streams at once Caleb's and freaks doesn't your brain explode if you try to do that yeah there are a lot of people streaming I guess maybe I should pick another moment to stream I think that like Friday is like the most the most popular day to do it but maybe I'll just do it on another day in in the future you guys are crazy yeah I guess so okay I guess if there are any more questions then we can call it today I had a lot of fun doing this I'll probably do this again I really like the informal feel what I don't like is that I don't have like a way to see any of you or talk any of you because now would be like a good time to have some some interaction maybe I'll figure that out for the next time but for now I guess we're done thank you all for for watching and I guess have a nice weekend and see you some other time bye bye you
Info
Channel: Freek Van der Herten
Views: 9,501
Rating: undefined out of 5
Keywords:
Id: 1bucfsyAZtI
Channel Id: undefined
Length: 57min 40sec (3460 seconds)
Published: Fri May 29 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.