插入相关模型时如何覆盖'create'方法。 Laravel 5.5

时间:2018-03-31 08:43:14

标签: php laravel laravel-5 orm method-overriding

我想插入一个与用户相关的新事件(如派对等),所以我根据this教程执行此操作。这是在0内。

EventsService.php

我按照答案的建议在public function store( StoreEventRequest $request, $dashboard = false ) { $owner = User::find( $request->owner_id ); try { $event = $owner->events()->create( $request->all() ); } catch ( \Exception $exception ) { throw new Exception( $exception->getMessage() ); } $this->interestsService->updateFromRequest( $event ); if ( $request->hasFile( 'photos' ) ) { $event->photosFromRequest( $request ); } if ( $request->hasFile( 'cover_photo' ) ) { $event->coverPhotoFromRequest( $request ); } return $event->fresh(); } 内添加了filterByPrivacy()

StoreEventRequest.php

问题是public function filterByPrivacy() { error_log(('Im here.')); if ($this->privacy == "private") { $this->request->set('access_code', $this->getAccessCodeAttribute()); } else { $this->request->set('access_code', null); } } 永远不会被打印,同一类中的其他方法也会打印。

2 个答案:

答案 0 :(得分:1)

在模型中创建启动方法,创建在创建方法调用之前执行的statuc函数

 public static function boot()
    {
        parent::boot();

        static::creating(function($model)
        {
            dd($model);
        });
    }

答案 1 :(得分:1)

这就是我要做的事 - 我的假设是你试图在控制器内创建这些事件(如果我错了,请纠正我):

首先为此特定操作创建新请求:

php artisan make:request StoreEventRequest

这将添加新的请求文件app/Http/Requests/StoreEventRequest.php

请求文件的建议结构(请替换注释以满足您的要求):

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreEventRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize(): bool
    {
        // this should probably be handled by middleware           
        $user = $this->user();

        return $user && ($user->isAdmin() || $user->isActive());
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        $rules = [
            'id' => 'exists:events,id',
            'name' => 'required|min:5|max:255',
            'description' => 'required|max:1000',
            'city_id' => 'exists:cities,id',
            'country_id' => 'exists:countries,id',
            'location_address' => 'required|string',
            'location_latitude' => 'latitude',
            'location_longitude' => 'longitude',
            'privacy' => 'in:public,private',
            'budget' => 'numeric|min:0',
            'photos.*' => 'image',
            'cover_photo' => 'image',
            'min_attendees' => 'integer|min:0',
            'max_attendees' => 'integer|min:0',
            'starts_at' => 'required|date|after:now',
            'ends_at' => 'required|date|after:starts_at',
        ];

        if ($this->user()->isAdmin()) {

            //administrator special validation and overrides
            $rules['description'] = 'max:5000';
            $rules['location_address'] = 'string';
        }

        return $rules;
    }

    /**
     * Get processed request data.
     *
     * @return array
     */
    public function data(): array
    {
        $data = array_merge(
            $this->only([
                'id',
                'name',
                'description',
                'city_id',
                'country_id',
                'location_address',
                'location_latitude',
                'location_longitude',
                'privacy',
                'budget',
                'photos.*',
                'cover_photo',
                'min_attendees',
                'max_attendees',
                'starts_at',
                'ends_at',
            ]),
            [
                'access_code' => null
            ]
        );

        if ($data['privacy'] === "private") {
            $data['access_code'] = $this->accessCode();
        }

        return $data;
    }

    /**
     * Get access code.
     *
     * @return int
     */
    private function accessCode(): int
    {
        return rand(1000, 99999);
    }
}

我正在假设路线中存在owner_id

// routes/web.php
Route::post('event/{owner_id}/store', 'EventController@store')->name('event.store');

// app/Providers/RouteServiceProvider.php
public function boot()
{
    parent::boot();

    Route::model('owner_id', User::class);
}

这样我们的控制器方法可以直接将其作为依赖项使用(我已删除了您的try/catch,因为它似乎除了重新投掷之外什么都不做) :

public function store(StoreEventRequest $request, User $owner, $dashboard = false)
{
    $event = $owner->events()->create($request->data());

    $this->interestsService->updateFromRequest($event);

    if ($request->hasFile('photos')) {
        $event->photosFromRequest($request);
    }

    if ($request->hasFile('cover_photo')) {
        $event->coverPhotoFromRequest($request);
    }

    return $event->fresh();
}

我不确定$dashboard论证的来源,所以留在那里,但我相信这也会在路线上注册。

快速测试可以让您更深入地了解可能失败的内容:

php artisan make:test EventTest

及其内容:

<?php

namespace Tests\Feature;

use App\User;
use Tests\TestCase;

use Illuminate\Foundation\Testing\RefreshDatabase;

class EventTest extends TestCase
{
    use RefreshDatabase;

    /**
     * @test
     */
    public function passes_validation()
    {
        $user = factory(User::class)->create();

        $response = $this->post(route('event.store', $user->id), [
            // ... your request data goes here
        ]);

        // update response status to whatever you expect it to be
        // I've used 201 for CREATED
        $response->assertStatus(201);
    }
}

通过这种方式,您可以按照create方法的方式准备所有数据 - 无需覆盖它。

希望这有帮助。