Skip to content
This repository has been archived by the owner on Dec 10, 2018. It is now read-only.

Usage with Laravel Nova #80

Closed
vpratfr opened this issue Oct 22, 2018 · 5 comments
Closed

Usage with Laravel Nova #80

vpratfr opened this issue Oct 22, 2018 · 5 comments

Comments

@vpratfr
Copy link
Collaborator

vpratfr commented Oct 22, 2018

Has anyone successfully managed to setup Nova with Binary UUIDs?

Currently trying to do so, but it seems to be a loooonnnnnggggg way till I get it to work.

Several reports here and there of people not being able to use it even with String UUIDs ...

@vpratfr
Copy link
Collaborator Author

vpratfr commented Oct 22, 2018

Related Nova support issue for reference: laravel/nova-issues#873

@brendt
Copy link
Contributor

brendt commented Oct 22, 2018

That issue link seems to be a 404. Maybe because of GitHub being messed up?

@vpratfr
Copy link
Collaborator Author

vpratfr commented Oct 22, 2018

Link is working here.

@uwascan
Copy link

uwascan commented Oct 23, 2018

I am able to create records but get a 404 when Nova redirects to the newly created record detail page. But index page works fine. I have tried a lot of tricks but keep getting 404 after creating a new record. Here is my code

use Spatie\BinaryUuid\HasBinaryUuid;
use Illuminate\Database\Eloquent\Model;

abstract class BaseModel extends Model
{
    use HasBinaryUuid;

    public $incrementing = false;

    public function getKeyName()
    {
        return 'id';
    }

    /**
     * Get the value of the model's route key.
     *
     * @return mixed
     */
    public function getRouteKey()
    {
        return $this->decodeUuid($this->attributes['id']);
    }

    public function getIdAttribute()
    {
        if(array_key_exists('id', $this->attributes)) {
            return $this->decodeUuid($this->attributes['id']);
        }
        return null;
    }
}

class Product extends BaseModel
{
    protected $table = 'products';

        /**
     * The binary UUID attributes that should be converted to text.
     *
     * @var array
     */
    protected $uuids = [
        'id' // foreign or related key
    ];

}

In Base Resource, I had to override detailQuery to transform string uuid back to binary uuid but still no luck even when the log statement returns the right record

use Ramsey\Uuid\Uuid;
use Laravel\Nova\Resource as NovaResource;
use Laravel\Nova\Http\Requests\NovaRequest;

abstract class Resource extends NovaResource
{
    public static function hasUUIDKey()
    {
        return false;
    }

    public static function encodeUuid($uuid): string
    {
        if (! Uuid::isValid($uuid)) {
            return $uuid;
        }

        if (! $uuid instanceof Uuid) {
            $uuid = Uuid::fromString($uuid);
        }

        return $uuid->getBytes();
    }
    
     ...

    /**
     * Build a "detail" query for the given resource.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function detailQuery(NovaRequest $request, $query)
    {
        if(static::hasUUIDKey()) {
           //  the log statement returns the right record
            info(json_encode($request->model()::withUuid($request->resourceId)->first(), JSON_PRETTY_PRINT));
            return $request->model()::withUuid($request->resourceId);
        }
        return parent::detailQuery($request, $query);
    }

}

Product Resource

use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Date;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\TextArea;
use Laravel\Nova\Fields\Boolean;

use Illuminate\Http\Request;
use Laravel\Nova\Http\Requests\NovaRequest;

class Product extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = \App\Models\Product::class;

    /**
     * The single value that should be used to represent the resource when being displayed.
     *
     * @var string
     */
    public static $title = 'name';

    public static $category = "Catalogs";

    /**
     * The columns that should be searched.
     *
     * @var array
     */
    public static $search = [
        'name',
    ];

    public static function hasUUIDKey()
    {
        return true;
    }

    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Text::make("Name")->sortable(),
            TextArea::make("description")->onlyOnForms(),
            Boolean::make("Active?", "is_active"),
            Date::make('Created', 'created_at')->onlyOnIndex(),
        ];
    }

    /**
     * Get the cards available for the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function cards(Request $request)
    {
        return [];
    }

    /**
     * Get the filters available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function filters(Request $request)
    {
        return [];
    }

    /**
     * Get the lenses available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function lenses(Request $request)
    {
        return [];
    }

    /**
     * Get the actions available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function actions(Request $request)
    {
        return [];
    }
}

Any idea how to make this work?

@freekmurze
Copy link
Member

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants