artificertech / laravel-relationship-events
Laravel缺少关系事件
Requires
- php: ^7.4|^8.0
- illuminate/container: ^8.0|^9.0|^10.0
- illuminate/database: ^8.0|^9.0|^10.0
- illuminate/events: ^8.0|^9.0|^10.0
- illuminate/support: ^8.0|^9.0|^10.0
Requires (Dev)
- orchestra/testbench: ^6.0|^7.0|^8.0
- phpunit/phpunit: ^9.0|^9.3|^9.5
This package is auto-updated.
Last update: 2024-08-29 07:26:44 UTC
README
Laravel缺少关系事件
此包最初是从https://github.com/chelout/laravel-relationship-events 分支的代码派生而来,该分支不再积极开发。此包对原始想法进行了不同的实现,允许基于每个关系创建关系事件监听器
此包仍在开发中。欢迎通过提交拉取请求进行贡献
安装
- 使用composer安装包
最新版本
由于该项目仍在开发中,因此目前没有发布版本。
composer require artificertech/laravel-relationship-events
开发分支
composer require artificertech/laravel-relationship-events:dev-master
- 将HasRelationshipEvents特性添加到您的模型中
use Artificertech\RelationshipEvents\Concerns\HasRelationshipEvents; use Illuminate\Database\Eloquent\Model; class User extends Model { use HasRelationshipEvents; public static function boot() { parent::boot(); /** * hasOne */ static::hasOneSaved('profile', function ($user, $profile) { dump('hasOneSaved', $user, $profile); }); } public function profile() { return $this->hasOne(Profile::class)->withEvents(); } }
对于所有在操作执行之前触发的保存、附加、创建等事件,您可以从不从事件监听器返回false以取消操作
use Artificertech\RelationshipEvents\Concerns\HasRelationshipEvents; use Illuminate\Database\Eloquent\Model; class User extends Model { use HasRelationshipEvents; public static function boot() { parent::boot(); /** * hasMany */ static::hasManyCreating('posts', function ($user, $post) { if ($post->name == 'badName') return false; }); } public function posts() { return $this->hasMany(Post::class)->withEvents(); } }
- 可分发的关联事件。可以通过$dispatchesEvents属性来通过事件类触发事件
use Artificertech\RelationshipEvents\Concerns\HasRelationshipEvents; use Illuminate\Database\Eloquent\Model; class User extends Model { use HasRelationshipEvents; protected $dispatchesEvents = [ 'postsCreating' => UserPostsCreating::class, 'postsCreated' => UserPostsCreated::class, 'postsSaving' => UserPostsSaving::class, 'postsSaved' => UserPostsSaved::class, ]; public function posts() { return $this->hasMany(Post::class)->withEvents(); } }
观察者
您可以在Laravel观察者类中使用关系事件。使用非常简单。定义观察者类
namespace App\Observer; class UserObserver { /** * Handle the User "postsCreating" event. * * @param \App\Models\User $user * @param \App\Models\Post $post * * @return void */ public function postsCreating(User $user, Post $post) { Log::info("Creating post: {$post->name} for user {$user->name}."); } /** * Handle the User "postsCreated" event. * * @param \App\Models\User $user * @param \App\Models\Post $post * * @return void */ public function postsCreated(User $user, Post $post) { Log::info("Post: {$post->name} for user: {$user->name} has been created."); } /** * Handle the User "postsCreating" event. * * @param \App\Models\User $user * @param \App\Models\Post $post * * @return void */ public function postsSaving(User $user, Post $post) { Log::info("Saving post: {$post->name} for user {$user->name}."); } /** * Handle the User "postsCreated" event. * * @param \App\Models\User $user * @param \App\Models\Post $post * * @return void */ public function postsSaved(User $user, Post $post) { Log::info("Post: {$post->name} for user: {$user->name} has been saved."); } }
检测可观察事件
laravel-relationship-events包不能自动检测您想要观察的关系事件。请像这样在您的模型类中定义它们
class User extends Model { use HasRelationshipEvents; /** * User exposed observable events. * * These are extra user-defined events observers may subscribe to. * * @var array */ protected $observables = [ 'postsCreating', 'postsCreated', 'postsSaving', 'postsSaved', ]; public function posts() { return $this->hasMany(Post::class)->withEvents(); } }
别忘了在AppServiceProvider的boot方法中注册观察者
namespace App\Providers; use App\Models\User; use App\Observers\UserObserver; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { // ... public function boot() { User::observe(UserObserver::class); } // ... }
现在只需为用户创建配置文件
// ... $user = factory(User::class)->create([ 'name' => 'John Smith', ]); // Create profile and assosiate it with user // This will fire two events hasOneCreating, hasOneCreated $user->post()->create([ 'name' => 'My first post!', ]); // ...
自定义事件名称
默认情况下,关系事件名称等于关系函数名称,动作以驼峰式表示。例如,如果您有一个HasOne关系"profile",则事件名称将是"profileCreating"、"profileCreated"、"profileSaving"、"profileSaved"。
您可以通过将关系名称作为字符串传递给withEvents()函数来自定义事件名称。例如
class User extends Model { use HasRelationshipEvents; public function posts() { return $this->hasMany(Post::class)->withEvents('userPost'); } }
将触发"userPostCreating"、"userPostCreated"、"userPostSaving"、"userPostSaved"事件
关系特定信息
每个关系都有稍微不同的事件。例如,belongsTo关系触发{relationship}Associating、{relationship}Associated、{relationship}Dissociating和{relationship}Dissociated事件
待办事项
- 修复自动测试
- 添加ManyToMany类型事件的文档(这些事件可以通过内置的pivot模型处理,不需要此包)
- 非默认事件名称测试
- 事件调度器测试
- 事件监听器异常测试
- HasOneThrough & HasManyThrough
- 新HasOneOfMany关系?