<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: ARK DEV SOLUTIONS</title>
    <description>The latest articles on Forem by ARK DEV SOLUTIONS (@arkdevsolutions).</description>
    <link>https://forem.com/arkdevsolutions</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1203074%2Fd1593788-e56f-4744-9f4d-d90a0ef5002c.png</url>
      <title>Forem: ARK DEV SOLUTIONS</title>
      <link>https://forem.com/arkdevsolutions</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/arkdevsolutions"/>
    <language>en</language>
    <item>
      <title>When Should You Create Views in Your Database?</title>
      <dc:creator>ARK DEV SOLUTIONS</dc:creator>
      <pubDate>Sat, 21 Dec 2024 10:52:53 +0000</pubDate>
      <link>https://forem.com/arkdevsolutions/when-should-you-create-views-in-your-database-52hb</link>
      <guid>https://forem.com/arkdevsolutions/when-should-you-create-views-in-your-database-52hb</guid>
      <description>&lt;p&gt;Creating views in a database can offer significant performance improvements and simplifications, particularly when dealing with complex queries or aggregations. In this article, we'll explore when to use views and materialized views in your database, why they are useful, and how they can optimize your system's performance for faster results.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Database Views?
&lt;/h2&gt;

&lt;p&gt;A view in a database is a stored query that can be treated like a table. Views are not physical but virtual tables that provide an abstraction layer over your database schema. The query underlying a view is executed each time the view is queried, simplifying complex queries or aggregations.&lt;/p&gt;

&lt;p&gt;Materialized views are similar but differ in that they store the query results physically, updating periodically or on-demand, which can lead to significant performance benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Create Views in the Database
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Complex Joins and Aggregations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your queries involve multiple tables with complex joins and aggregations, creating a view can simplify the query structure and improve performance. For example, joining data from articles, authors, and tags can become tedious if repeated in every query. Instead, you can create a view that encapsulates the complex logic.&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7hrzm69o4mhzl0dhgnl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7hrzm69o4mhzl0dhgnl.png" alt="Image description" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, querying the view is simple and avoids repetitive joins:&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszwdv6vmrzlodcfczpdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszwdv6vmrzlodcfczpdw.png" alt="Image description" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is much faster than executing multiple joins every time you need this data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Frequent and Repetitive Queries&lt;/strong&gt;&lt;br&gt;
If your application runs the same complex query frequently (for example, generating monthly reports), a view can save time and reduce query complexity. By using a view, you avoid duplicating the same SQL code in different parts of the application.&lt;/p&gt;

&lt;p&gt;For example, suppose you're generating reports that frequently fetch the same dataset (like top articles by views or sales). In that case, you can create a view that predefines the logic, ensuring consistency and faster access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Encapsulation of Business Logic&lt;/strong&gt;&lt;br&gt;
Views can encapsulate business rules, complex filters, or data transformations that would otherwise need to be repeated throughout your application. This reduces the risk of errors and improves maintainability.&lt;/p&gt;

&lt;p&gt;Example: You could encapsulate business logic that combines user, article, and tag information in a single view, ensuring all parts of your application query the same logic without duplicating it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Performance Optimization (Materialized Views)&lt;/strong&gt;&lt;br&gt;
While regular views do not store data physically and thus do not inherently speed up queries, materialized views are a special case. Materialized views store the result of a query physically, so you can query them like a table, avoiding the need to recompute the result each time.&lt;/p&gt;

&lt;p&gt;This is especially useful for complex aggregations, reporting, or data warehousing scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; For a reporting system, instead of joining articles, users, and tags every time you generate a report, you could create a materialized view:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3nyaaxd40i54bkglzao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3nyaaxd40i54bkglzao.png" alt="Image description" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, querying the materialized view is much faster than repeatedly executing the complex join queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Views?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Simplifies Queries&lt;/strong&gt;&lt;br&gt;
Views simplify your SQL queries by encapsulating complex logic into a single object. Instead of repeatedly writing complex joins, aggregations, or business logic, you can query a view like a table. This makes your application code cleaner, more maintainable, and less error-prone.&lt;/p&gt;

&lt;p&gt;For instance, instead of manually joining articles, authors, and tags every time, you can just query the article_summary view to retrieve the same result with a much simpler query:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7ysbcwxjd4fdsewyqn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7ysbcwxjd4fdsewyqn8.png" alt="Image description" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Performance Boost (Materialized Views)
In cases where querying complex joins or aggregations is slow, materialized views can significantly reduce query time by storing the result of the query physically. This is particularly helpful when you need to perform operations like:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Data aggregation (e.g., summing or counting rows).&lt;br&gt;
Data reporting (e.g., generating monthly or yearly reports).&lt;br&gt;
Data transformation (e.g., applying complex filters or business rules).&lt;br&gt;
With materialized views, the query results are precomputed and stored. As a result, querying the materialized view is much faster than running the same complex query repeatedly.&lt;/p&gt;

&lt;p&gt;For example, a materialized view for a report that aggregates monthly article views would avoid the need to recompute the results each time:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xlkyy6ds70vkyamrlaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xlkyy6ds70vkyamrlaz.png" alt="Image description" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Reduces Repetition and Duplication&lt;/strong&gt;&lt;br&gt;
If multiple parts of your application need the same complex query logic, views allow you to centralize this logic. Instead of copying and pasting SQL code or using application-level logic to repeat complex joins or filters, you can create a single view that encapsulates the logic. This avoids duplication and makes your code easier to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Improves Data Integrity&lt;/strong&gt;&lt;br&gt;
By abstracting complex logic in a view, you ensure that the same query logic is applied consistently across your application. This helps maintain data integrity and prevents discrepancies in how the data is queried or displayed. For example, if a calculation or transformation is part of the business logic, using a view ensures that it is always applied consistently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Provides Security and Access Control&lt;/strong&gt;&lt;br&gt;
Views allow you to abstract and control access to sensitive data. For example, you might want to expose certain data to different users but hide other sensitive information. You can create views that only expose certain columns or rows, thereby controlling what data is accessible.&lt;/p&gt;

&lt;p&gt;Example: You can create a view that exposes only non-sensitive user data:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwby5e3nvy85tpihvn305.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwby5e3nvy85tpihvn305.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way, users querying the view will not see sensitive columns such as passwords or credit card numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;p&gt;While views can optimize and simplify queries, they don’t automatically guarantee performance improvements. The actual performance benefits depend on how the view is used and whether it is a regular view or a materialized view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Regular Views
&lt;/h2&gt;

&lt;p&gt;No Performance Boost: Regular views don’t store data physically; they just store a query template. Every time you query a regular view, the underlying query is executed. This means complex queries using regular views may still take the same amount of time as the original query.&lt;br&gt;
Use for Simplification: Regular views are best used for simplifying queries and encapsulating business logic, but they may not always provide a performance boost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Materialized Views
&lt;/h2&gt;

&lt;p&gt;Precomputed Data: Materialized views store the result of the query and can significantly improve performance for complex reports, aggregations, or frequent read-heavy operations.&lt;br&gt;
Refresh Overhead: Materialized views need to be refreshed periodically to ensure they contain the latest data. This refresh process introduces some overhead, especially if the underlying data changes frequently.&lt;br&gt;
Space and Memory Usage: Materialized views consume storage space, and depending on the size of your dataset, they can increase disk usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Not to Use Views
&lt;/h2&gt;

&lt;p&gt;While views are useful in many scenarios, there are situations where you should avoid them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highly Dynamic Data:&lt;/strong&gt; If the underlying data changes frequently and the view needs to be refreshed often (in the case of materialized views), the overhead of maintaining the view might outweigh the performance benefits.&lt;br&gt;
&lt;strong&gt;Simple Queries:&lt;/strong&gt; If your query is simple and doesn’t involve complex joins, subqueries, or aggregations, creating a view may add unnecessary complexity to your database structure.&lt;br&gt;
Performance Degradation with Regular Views: Since regular views execute queries every time they are queried, they can degrade performance, especially when dealing with large datasets or complex queries. In such cases, it’s better to avoid views or use them selectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Creating views in the database can be a powerful tool for optimizing query performance, simplifying complex queries, and ensuring consistency across your application. You should create views when you need to:&lt;/p&gt;

&lt;p&gt;Simplify complex joins, aggregations, or business logic.&lt;br&gt;
Eliminate repetitive query writing.&lt;br&gt;
Improve data security and control access to sensitive data.&lt;br&gt;
For performance-sensitive use cases, materialized views provide precomputed query results, reducing the need for repeated computations and significantly improving performance. However, be mindful of the refresh overhead and space requirements.&lt;/p&gt;

&lt;p&gt;Ultimately, use views strategically to enhance both the maintainability and performance of your database, ensuring fast and efficient results when working with large datasets or complex queries.&lt;/p&gt;

</description>
      <category>database</category>
      <category>laravel</category>
      <category>mysql</category>
      <category>databaseviews</category>
    </item>
    <item>
      <title>Multi tenancy connect with tenant DB without Initialization Or Dynamically</title>
      <dc:creator>ARK DEV SOLUTIONS</dc:creator>
      <pubDate>Thu, 03 Oct 2024 12:41:15 +0000</pubDate>
      <link>https://forem.com/arkdevsolutions/multi-tenancy-connect-with-tenant-db-without-initialization-or-dynamically-2hco</link>
      <guid>https://forem.com/arkdevsolutions/multi-tenancy-connect-with-tenant-db-without-initialization-or-dynamically-2hco</guid>
      <description>&lt;p&gt;&lt;strong&gt;Multi-Tenancy Without Initialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a typical multi-tenancy setup, packages like Stancl/Tenancy are used to initialize tenant context by switching configurations automatically, including the database connection. This involves loading a tenant's specific configuration (like database credentials) after "initializing" the tenancy environment. However, in this case, we're avoiding explicit tenancy initialization and manually connecting to the tenant's database dynamically.&lt;/p&gt;

&lt;p&gt;Follow the Steps&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrieving Tenant Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0wmiupnt1egu06p6ke0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0wmiupnt1egu06p6ke0.png" alt="Image description" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code starts by retrieving the Tenant record from the central database using the sport_id. This allows us to extract tenant-specific details, such as the database name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error Handling for Tenant Existence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2328681oa9jygzbku5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2328681oa9jygzbku5y.png" alt="Image description" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The system ensures that if the Tenant cannot be found using the provided sport_id, it returns an error message to prevent any further processing, ensuring graceful failure handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamically Setting Tenant Database Connection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zm37u7zy8o6xiruqdtw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zm37u7zy8o6xiruqdtw.png" alt="Image description" width="800" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's where the core dynamic connection logic happens:&lt;br&gt;
Manual Configuration: Laravel's config() helper is used to set a new database connection (tenant). This configuration is created on the fly based on the tenant’s database name ($tenantDBName) and uses environment variables for common settings like host, username, and password.&lt;br&gt;
This essentially creates a new connection for this request without altering the default connection defined in Laravel's database.php config file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Tenant Connection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2yf1do1chqm6okyrubd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2yf1do1chqm6okyrubd.png" alt="Image description" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;on('tenant'): The method .on('tenant') explicitly tells Laravel's Eloquent ORM to use the dynamically created tenant database connection (tenant). This ensures that the queries for fetching the article and its relationships are run against the tenant’s specific database, not the central one.&lt;br&gt;
Eager Loading: The code uses Eloquent's with() method to eager load related models like subjects, image, and author. This allows for more efficient database queries by reducing the number of individual queries that would otherwise be required to retrieve these relationships.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error Handling for Article (or your Model) Retrieval&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsly6z95y1j23w2obcomu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsly6z95y1j23w2obcomu.png" alt="Image description" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the event that the article cannot be found in the tenant’s database, the system gracefully handles the error by redirecting back with an appropriate message.&lt;/p&gt;

&lt;p&gt;Few more things to consider and understand ...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages of This Approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No Global Tenancy Initialization:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In certain scenarios, initializing a global tenancy environment across requests can be resource-heavy or unnecessary, especially if all you need is to perform isolated operations on a tenant’s database. This approach allows you to connect directly to the tenant’s database when needed, without initializing tenancy for the entire application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scalability and Flexibility:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By setting database connections dynamically on a per-request basis, the application is more flexible in handling a large number of tenants. Each tenant’s connection is isolated and only created when necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Case:&lt;/strong&gt;&lt;br&gt;
This approach is particularly useful in applications where you have different databases for tenants but share most other resources, like codebase, environment settings, or other global configurations. This technique avoids the overhead of multi-tenant packages but still provides isolation for database-related operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database Connections Per Request:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every time this method is called, it dynamically sets a new connection. While efficient for small-scale applications, this could become resource-intensive for a high number of concurrent users or tenants. Managing the lifecycle of these connections should be done carefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The above code effectively handles dynamic multi-tenancy by connecting to a tenant’s database without using a tenancy package or initializing a global tenancy context. This approach offers flexibility, especially for applications where only certain operations need to be tenant-aware, and avoids the complexity and overhead of managing tenancy at a global level.&lt;/p&gt;

&lt;p&gt;It's an elegant solution for applications with isolated tenant databases but shared application logic and infrastructure, aligning well with Laravel's philosophy of simplicity and flexibility.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>multitenancy</category>
      <category>webcomponents</category>
      <category>laravel</category>
    </item>
    <item>
      <title>How to Setup Multi Tenant App in minutes with Laravel PART 2</title>
      <dc:creator>ARK DEV SOLUTIONS</dc:creator>
      <pubDate>Thu, 05 Sep 2024 07:53:21 +0000</pubDate>
      <link>https://forem.com/arkdevsolutions/how-to-setup-multi-tenant-app-in-minutes-with-laravel-part-2-5560</link>
      <guid>https://forem.com/arkdevsolutions/how-to-setup-multi-tenant-app-in-minutes-with-laravel-part-2-5560</guid>
      <description>&lt;p&gt;&lt;strong&gt;Now your first multitenancy app is ready to go live and you can test on local but for that you need to create a TenantController from where you can register the tenants&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfzkocw36kifl5bf7ez0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfzkocw36kifl5bf7ez0.png" alt="Image description" width="800" height="2457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;this will be basic code you can modify it for more stuff as per your requirements&lt;/p&gt;

&lt;p&gt;now you will need to modify your route service provider if you havent set it accordingly &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujhkfvibi7lxui2wdd30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujhkfvibi7lxui2wdd30.png" alt="Image description" width="800" height="1124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now you can set you web.php and tenant.php file accordingly &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;web.php&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7836x4xa81axo6uriqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7836x4xa81axo6uriqw.png" alt="Image description" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tenant.php&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6rc7hk67kr1dasvo6lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6rc7hk67kr1dasvo6lw.png" alt="Image description" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now your app is up and ruining please make modification as per your requirements &lt;/p&gt;

</description>
      <category>laravel</category>
      <category>saas</category>
      <category>php</category>
      <category>backend</category>
    </item>
    <item>
      <title>How to Setup Multi Tenant App in minutes with Laravel</title>
      <dc:creator>ARK DEV SOLUTIONS</dc:creator>
      <pubDate>Mon, 06 Nov 2023 10:53:51 +0000</pubDate>
      <link>https://forem.com/arkdevsolutions/how-to-setup-multi-tenant-app-in-minutes-with-laravel-5d0d</link>
      <guid>https://forem.com/arkdevsolutions/how-to-setup-multi-tenant-app-in-minutes-with-laravel-5d0d</guid>
      <description>&lt;p&gt;In this article you will learn how to setup the basic Laravel multi tenant app in minutes with some simple steps.&lt;/p&gt;

&lt;p&gt;Multi tenancy is a good concepts for new SaaS based Applications it will help you to keep the one codebase for multiple domains and each domain contains its own data.&lt;/p&gt;

&lt;p&gt;Let get Started!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new Laravel Project&lt;/li&gt;
&lt;li&gt;Install/setup Laravel Breeze&lt;/li&gt;
&lt;li&gt;Install multitenancy package with following command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require stancl/tenancy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;After it completes run the following command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan tenancy:install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will create:&lt;/p&gt;

&lt;p&gt;migrations&lt;br&gt;
a config file (config/tenancy.php),&lt;br&gt;
a routes file (routes/tenant.php),&lt;br&gt;
and a service provider file &lt;br&gt;
app/Providers/TenancyServiceProvider.php&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recap&lt;br&gt;
What we have done so far&lt;br&gt;
a. create a new project&lt;br&gt;
b. install tenancy package&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step for multiple domains and database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the above steps are done we need to register our tenancy service provider in the following file&lt;br&gt;
Then add the service provider to your config/app.php file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0y33s3g9qf6at78uzmbo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0y33s3g9qf6at78uzmbo.png" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to create a Tenant Model for that we will use following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:model Tenant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that a model will Created in side the App/Models/ we need to change the code with following later we will update it more according to our needs&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc946bdsahi6evhkjnlzc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc946bdsahi6evhkjnlzc.png" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;by default it will use the package Tenant Model but we want the system to use our model that we have just created for that we have to go in the config folder/directory and then find the tenancy.php file and make the following changes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'tenant_model' =&amp;gt; Tenant::class,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;change the Above line of code with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'tenant_model' =&amp;gt; \App\Models\Tenant::class,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;If you don't need domains or databases, ignore the steps above. Everything will work just as well.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can create tenants like any other models:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq441lyiazu3v0avtbf1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq441lyiazu3v0avtbf1w.png" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may register central routes in routes/web.php or routes/api.php like you're used to. However, you need to make one small change to your RouteServiceProvider.&lt;br&gt;
You don't want central routes — think landing pages and sign up forms — to be accessible on tenant domains. For that reason, register them in such a way that they're only accessible on your central domains.Now we need to set the routes for the tenants and central app&lt;br&gt;
let go the the RouteServiceProvider.php and replace the code with following code from boot function&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e71jgd44rn212v407qv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e71jgd44rn212v407qv.png" alt="Image description" width="800" height="852"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tenant routes&lt;/strong&gt;&lt;br&gt;
You may register tenant routes in routes/tenant.php file&lt;br&gt;
by default it will look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1fwe4ofi2lcnhlf7hnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1fwe4ofi2lcnhlf7hnq.png" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to create copy the migration files from migration folder to the tenant folder that resides in migration folder and copy the required migration files&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouc1bstragznt8l611lk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouc1bstragznt8l611lk.png" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;once this done we need to create a job that will insert the data in tenant table and also generate the tenant database and insert that record in it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:job SeedTenantJob
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and replace the file code with the code bellow&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3g3c5n7a76osvc3dkpqh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3g3c5n7a76osvc3dkpqh.png" width="800" height="716"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;what this file do is it will always run as soon as you will hit the create tenant function and once it will be execute it will run the migration and insert the first record for you so you can login and access your tenant application&lt;/p&gt;

&lt;p&gt;but still we have to do some more fix's to get the working tenant application&lt;/p&gt;

&lt;p&gt;now we need to do some modifications in TenantServiceProvider.php &lt;br&gt;
do the following changes&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmygkvmruy4aon8f5zob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmygkvmruy4aon8f5zob.png" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;uncomment the JobSeedDatabase and add our created job bellow that \App\Jobs\SeedTenantJob::class&lt;/p&gt;

&lt;p&gt;like mentioned in the picture. Remember that order is very important in this file if you put our job at top and JobSeedDatabase bellow that it will throw error as you need to first run the migrations then insert the data our job part is for the insertion of data and JobSeedDatabase is to run the migrations&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now your first multitenancy app is ready to go live and you can test on local but for that you need to create a TenantController from where you can register the tenants&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfzkocw36kifl5bf7ez0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfzkocw36kifl5bf7ez0.png" alt="Image description" width="800" height="2457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;this will be basic code you can modify it for more stuff as per your requirements&lt;/p&gt;

&lt;p&gt;now you will need to modify your route service provider if you havent set it accordingly &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujhkfvibi7lxui2wdd30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujhkfvibi7lxui2wdd30.png" alt="Image description" width="800" height="1124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now you can set you web.php and tenant.php file accordingly &lt;/p&gt;

&lt;p&gt;** updated web.php**&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7836x4xa81axo6uriqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7836x4xa81axo6uriqw.png" alt="Image description" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;updated tenant.php&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6rc7hk67kr1dasvo6lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6rc7hk67kr1dasvo6lw.png" alt="Image description" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>multitenancy</category>
      <category>laraveltenant</category>
      <category>saas</category>
    </item>
  </channel>
</rss>
