使用与其他模型的策略的关系

时间:2017-10-16 19:37:59

标签: php laravel laravel-5.5

我使用的是Laravel v5.5.14。

App\Message中的routes/api.php我有一个端点:

Route::group(['middleware' => 'auth:api'], function() {

    Route::put('messages/{message}', 'MessageController@update')->middleware('can:view,pet');

});

我想应用我can:view,pet中定义的PetPolicy.php政策:

namespace App\Policies;

use App\User;
use App\Pet;
use Illuminate\Auth\Access\HandlesAuthorization;

class PetPolicy
{
    use HandlesAuthorization;

    public function view(User $user, Pet $pet)
    {
        return $user->pets()->where('pet_id', $pet->id)->exists();
    }
}

每个App\Message都有App\Pet我声明宠物在我的模型中有很多消息(一对多)关系。每个App\User都可以有多个App\Pet多对多。

app/Pet.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Pet extends Model
{
    protected $fillable = ['name'];

    public function messages()
    {
        // one-to-many hasMany belongsTo
        return $this->hasMany('App\Message');
    }

    public function users()
    {
        // many-to-many belongsToMany "
        return $this->belongsToMany('App\User');
    }
}

app/Message.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    protected $fillable = ['body', 'kind'];

    public function pet()
    {
        // one-to-many hasMany belongsTo
        return $this->belongsTo('App\Pet');
    }
}

app/User.php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    // ....

    public function pets()
    {
        // many-to-many belongsToMany "
        return $this->belongsToMany('App\Pet');
    }    

    public function messages()
    {
        // one-to-many hasMany belongsTo
        return $this->hasMany('App\Message');
    }
}

但是我的政策失败了,它总是给予未经授权。我在某个地方犯了错误吗?

这是我的app/AuthServiceProvider.php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    protected $policies = [
        'App\Pet' => 'App\Policies\PetPolicy',
        'App\Message' => 'App\Policies\MessagePolicy'
    ];

    public function boot()
    {
        $this->registerPolicies();
    }
}

由于

1 个答案:

答案 0 :(得分:2)

使用此查询进行测试:

namespace App\Policies;

use App\User;
use App\Pet;
use Illuminate\Auth\Access\HandlesAuthorization;

class PetPolicy
{
    use HandlesAuthorization;

    public function view(User $user, Pet $pet)
    {
        return User::where('id', $user->id)
                    ->whereHas('pets', function ($query) use($pet) {
                            $query->where('id', $pet->id);
                        })
                    ->exists();
    }
}

如果您愿意,也可以这样:

return $user->pets->contains($pet->id);

或者像这样:

return DB::table('pet_user')
    ->whereUserId($user->id)
    ->wherePetId($pet->id)
    ->count() > 0;
相关问题