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

Php 使用与其他模型的策略的关系,php,laravel,laravel-5.5,Php,Laravel,Laravel 5.5,我使用的是Laravel v5.5.14 我有一个端点,用于routes/api.php中的App\Message: Route::group(['middleware' => 'auth:api'], function() { Route::put('messages/{message}', 'MessageController@update')->middleware('can:view,pet'); }); namespace App; use Illumina

我使用的是Laravel v5.5.14

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

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

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

});
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');
    }
}
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');
    }
}
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');
    }
}
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();
    }
}
我想应用在我的
PetPolicy.php
中定义的
can:view,pet
策略:

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

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

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

});
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');
    }
}
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');
    }
}
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');
    }
}
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();
    }
}
app/Message.php

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

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

});
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');
    }
}
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');
    }
}
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');
    }
}
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();
    }
}
app/User.php

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

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

});
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');
    }
}
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');
    }
}
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');
    }
}
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();
    }
}
无论我的政策如何失败,它总是在未经授权的情况下给予。我在什么地方出错了吗

这是我的
app/AuthServiceProvider.php

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

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

});
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');
    }
}
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');
    }
}
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');
    }
}
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();
    }
}

谢谢

使用此查询测试它:

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;

你能给我们看一下
AuthServiceProvider
受保护的$policies
吗?这里没有问题,还有一件事你没有提到用户和宠物之间的关系!!啊,谢谢你@Maraboc这里的关系是多对多的。我将在上面编辑并更新。@Maraboc非常感谢您的耐心和帮助,我刚刚添加了它。非常感谢Maraboc的帮助,我认为这不是问题所在,因为我在另一个端点上成功地使用了它。我尝试了您的所有尝试,其他端点都可以工作(
/pets/{pet}
),但这一个不行。是因为
PetPolicy
中的第二个arg需要
Pet
,并且它可能会收到
Message
,因为我的url是
/messages/{messages}
而不是
/messages/{Pet}
。是的,我忘了先检查它。在这种情况下,您应该使用Message而不是Pet!!使用MessagePolicy,如果您仍然想要检查宠物,您可以这样做
returndb::table('pet_user')->whereUserId($user->id)->wherePetId($message->pet->id)->count()>0和其他情况相同,将
pet
替换为
$message->pet
;)非常感谢你的帮助!因为有你在我身边,这促使我快速学习!:)