Assign User to any Shop in Laravel Relationship?

梦想的初衷 提交于 2020-01-04 06:38:29

问题


In laravel, I have 3 table

 User // for Authentication and Create Another User Once logged in
 Expense
 Shop

My Purpose- I want user can register and Also, can create another user when they logged in And Can assign user to another Shop as they want..

And Only User in the Same Shop Can see their Expense..

// My User Table

<pre>
   Schema::create('users', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedBigInteger('shop_id')->nullable();
        $table->unsignedBigInteger('user_id')->nullable();
        $table->string('name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
</pre>

// My Expense Table

<pre>
    Schema::create('expenses', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedBigInteger('user_id');
        $table->date('date');
        $table->string('description');
        $table->double('amount');
        $table->timestamps();
        $table->foreign('user_id')->references('id')->on('users');
    });
</pre>

// My Shop Table

<pre>
     Schema::create('shops', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedBigInteger('expense_id')->nullable();
        $table->unsignedBigInteger('user_id');
        $table->string('name');
        $table->string('description');
        $table->timestamps();
        $table->foreign('expense_id')->references('id')->on('expenses');         
        $table->foreign('user_id')->references('id')->on('users');         
    });
</pre>

// My User Model

<pre>
   public function expense()
    {
        return $this->hasMany(\App\Expense::class);
    }


    public function shop()
    {
        return $this->hasMany(\App\Shop::class, 'user_id');
    }
</pre>

// My Expense Model

<pre>
class Expense extends Model
{
    protected $fillable = ['date', 'description', 'amount', 'user_id', 'shop_id'];

    public function user()
    {
        return $this->belongsTo(\App\User::class);  
    }

}
</pre>

// My Shop Model

<pre>
class Shop extends Model
{
    protected $fillable = ['name', 'description', 'expense_id', 'shop_id'];

    public function user()
    {
        return $this->belongsTo(\App\User::class, 'user_id');
    }

}
</pre>

// Expense Controller

<pre>
 public function index(Request $request)
    {
        $expense = Expense::with(['user'])->get();

        return ExpenseResource::collection($expense);

        // dd(auth()->user());
    }

    public function create(Request $request)
    {
        $request->validate([
            'date' => 'required',
            'description' => 'required',
            'amount' => 'required',

        ]);

        $expense = new Expense();
        $expense->user_id = auth()->user()->id;
        $expense->date = $request->date;
        $expense->description = $request->description;
        $expense->amount = $request->amount;
        $expense->save();

        return new ExpenseResource($expense);
    }
</pre>

// in My UserController

<pre>
public function index()
    {
        $users = User::all();
        $shops = Shop::all();
        return view('user', compact('users', 'shops'));
        // return UserResource::collection($users);
    }

    public function create(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'email' => 'required',
            'password' => 'required',
        ]);

        $user = new user();
        $user->user_id = auth()->user()->id;
        $user->name = $request->name;
        $user->email = $request->email;
        $user->password = bcrypt($request->password);
        $user->save();

        return new UserResource($user);
    }
</pre>

Is it make sense?

Any idea, thanks..


回答1:


As stated in the comments, you'll need to check the current User and constrain the returned Expense records to only those that 1) have a User and 2) match the same Store as the current User. This can be done in a single whereHas() clause:

public function index(Request $request) {
  $user = auth()->user(); // If using default `Auth` logic.

  $expenses = Expense::whereHas('user', function($subQuery) use($user){
    return $subQuery->where('shop_id', '=', $user->shop_id);
  })->with(['user'])->get();

  return ExpenseResource::collection($expenses);
}

What ->whereHas() does is constrains the query fetching your Expense models to respect the logic you pass it, which in this case is only include Expense models that have a user that has the same shop_id as the currently logged in User.

Note:If the current User does not have a Shop, it might return unexpected results, but you could protect the route to only allow a User with a Shop to access it, etc.



来源:https://stackoverflow.com/questions/57661443/assign-user-to-any-shop-in-laravel-relationship

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!