Summer Sale! All accounts are 50% off this week.

yougotnet's avatar

How to manage different data for a customer

I have an application where a customer will have different stores.

My question is, what is the best approach when the customer logs in and selects a store, that all the data for that store is served up throughout the application. Then when he logs out and logs back in, it defaults to that store he was on last.

Thanks!

0 likes
3 replies
LaryAI's avatar
Level 58

Solution:

You can achieve this by leveraging session variables to store the "active store" for the customer and also saving the last active store in the database (in the user's profile, for example) so you can restore it when the user logs back in.

Here's a high-level approach:

1. Update Customer Model

Add a field to your users (or customers) table to store last_store_id.

// migration example
Schema::table('users', function (Blueprint $table) {
    $table->unsignedBigInteger('last_store_id')->nullable();
});

2. Store Selected Store in Session

When the user selects a store, update the session and the user's last_store_id:

public function selectStore(Request $request, Store $store)
{
    // Put the store ID in session
    session(['current_store_id' => $store->id]);
    
    // Update user's last_store_id
    Auth::user()->update([
        'last_store_id' => $store->id
    ]);

    return redirect()->back();
}

3. Set Store on Login

When the user logs in, check if last_store_id is set, and put it in the session:

public function authenticated(Request $request, $user)
{
    if ($user->last_store_id) {
        session(['current_store_id' => $user->last_store_id]);
    }
}

Register this method in your LoginController. In Laravel, you can use the authenticated method for this:

// app/Http/Controllers/Auth/LoginController.php
protected function authenticated(Request $request, $user)
{
    if ($user->last_store_id) {
        session(['current_store_id' => $user->last_store_id]);
    }
}

4. Retrieve Data Based on Selected Store

Whenever you need to fetch store-specific data, use session('current_store_id'):

public function someControllerMethod()
{
    $storeId = session('current_store_id');
    $store = Store::findOrFail($storeId);

    // Fetch data related to this store
    $products = $store->products;
    // ...
}

5. Optional: Middleware for Store Context

If you want, you can create a middleware to ensure the session always has a store, redirecting the user to select one if not:

public function handle($request, Closure $next)
{
    if (!session('current_store_id')) {
        return redirect()->route('select.store');
    }
    return $next($request);
}

Apply this middleware to any routes that require a store context.


Summary:

  • Use a session variable to store the active store.
  • Save the last active store in the user/customer table.
  • Restore this when the user logs in.
  • Always fetch data using the store from the session.

This approach will make sure the app always serves up data for the selected store, and that the user's last-used store is remembered on re-login.

martinbean's avatar

@yougotnet I’ve worked on plenty of “multi-tenant” applications like this. Just keep things simple by using foreign keys and route parameters.

For example, one of my projects is a multi-tenant CMS (like Wix or Squarespace). When a user logs into the admin panel, if they belong to multiple websites then they can pick which website they want to manage. When they do, they’re then just redirected to the dashboard route (/websites/{website}/admin). The route group looks like this:

Route::group([
    'middleware' => ['auth', 'can:update,website'],
    'prefix' => 'websites/{website:slug}/admin',
], static function (): void {
    Route::get('/', DashboardController::class)->name('website.admin.dashboard');

    // Other website admin routes...
});

Each controller action then gets the current website injected as a parameter, so you can then scope model queries to that website:

namespace App\Http\Controllers\Admin;

class ArticleController extends Controller
{
    public function index(Website $website)
    {
        $articles = $website->articles()->paginate();

        return view('admin.article.index', compact('website', 'articles'));
    }

    public function store(Website $website, StoreArticleRequest $request)
    {
        $article = $website->articles()->create($request->validated());

        return redirect()
            ->route('website.admin.article.index')
            ->with('success', 'Article created.');
    }
}
vincent15000's avatar

You can simply add a field to the users table to save the last used store.

Please or to participate in this conversation.