tuyenlaptrinh's avatar

Eloquent Custom Table Name in Model

Hi Everyone!

I am working on one project. The ideal is I made custom table prefix for multi stores but use same Model.

My model:

table name maybe a1_brands, a2_brands, a3_brands..................

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Brand extends Model
{
    use HasFactory;
}

I am thinking solution for set custom table name in model.

I can use setTable when call query like this

Brand::setTable('a1_brands')->get();

but it can not set in relationships.

Can you suggest any more solutions.

Thank you so much

0 likes
14 replies
hupp's avatar
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Brand extends Model
{
    // Set the table name
    protected $table = $current_store . '_brand';
}

@tuyenlaptrinh you can set the table name direct in model itself using this. but here you have not mentioned more details. so try to find and replace $current_store variable value in the above snippet and test it. Hope it works. Let me know your feedback.

martinbean's avatar

@hupp That will throw an exception. You can’t use variables when setting a class property value like that.

tuyenlaptrinh's avatar

@hupp Thank you for quick response. I got your idea. But how to pass $current_store to Model. We can not use function in class variable like this

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Brand extends Model
{
	$current_store = app('current_store');
    // Set the table name
    protected $table = $current_store . '_brand';
}

This is begin project and in an ideal. I am looking solution for this

jaseofspades88's avatar

Why? It would be easier to have a column on your brands table to differentiate, perhaps type or something that suits your business need. One model, one table is generally considered the best practice, otherwise you're opening yourselves up to all manner of complications.

martinbean's avatar

@tuyenlaptrinh You don’t need “prefixes”, because that’s just going to become a pain in the ass to manage. If you have 100 stores, then you’re going to have to run migrations on as many tables, and what happens if the migrations fail part-way through? Your database is going to be left in a horrific, inconsistent state.

Instead, just use a relation. Create a model (and table) for stores, and then have a store_id foreign key in your brands table that connects that brand to a store. Or create a many-to-many relation and brand_store pivot table if a brand should be linked to multiple stores.

tuyenlaptrinh's avatar

Thank you @jaseofspades88 and @martinbean . My idea is like this

Store A:
- Warehouse A: 45000 products
- Warehouse B: 50000 products
- Warehouse C: 50000 products.
Store B:
..........

If I have 1000 stores. It will be increase products table maybe 5 millions - 20 millions products and It make slow in query.

I want to separate tables for per store

martinbean's avatar

@tuyenlaptrinh You do know relational databases like MySQL and PostgreSQL were literally created to hold millions and millions of rows, right…?

tuyenlaptrinh's avatar

@martinbean I know. But want to fast query. I am using one database with 3 millions records and It take more than 5 seconds for search records in table

tuyenlaptrinh's avatar

Thanks for all replies. @martinbean @hupp @jaseofspades88 @martinbean I got solution for this. I will make one middleware before request for set table prefix and define it.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Brand extends Model
{
    use HasFactory;
    protected $table = _PREFIX_DB_.'brands';
}
Snapey's avatar

@tuyenlaptrinh just learn about indexing and use a scope

As Martin says, you have chosen the most complicated and least maintainable solution

Please or to participate in this conversation.