L5如何使用具有哈希ID但保留支点功能的特征 [英] L5 How to use trait that hashes id but keep pivot functionality

查看:92
本文介绍了L5如何使用具有哈希ID但保留支点功能的特征的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用特征向ID添加了哈希.但是,现在这样做,我将无法再使用attach()或关系.

I added hashes to my ID's using a trait. However by doing that now I can no longer use attach() or relationships.

例如,这种关系在我看来不再起作用:

@foreach ($invoice->items as $item)
   {{ $item->item }}
@endforeach

以下是为我哈希ID的特征

<?php
namespace App\Traits;

use Hashids\Hashids;
use Illuminate\Database\Eloquent\Builder;

trait HashedId
{


    /**
     * Get the user's id as hashids.
     *
     * @param  $value
     * @return string
     */
    public function getIdAttribute($value)
    {
        $hashids = new \Hashids\Hashids(env('APP_KEY'),10);
        return $hashids->encode($value);
    }

    public function scopeHashId(Builder $query, $id)
    {
        $hashIds = new Hashids(env('APP_KEY'), 10);
        $id = $hashIds->decode($id)[0];

        return $query->where('id', $id);
    }
}

发票模型:

<?php

namespace App;

use App\Traits\HashedId;
use Illuminate\Database\Eloquent\Model;
use HipsterJazzbo\Landlord\BelongsToTenants;

class Invoice extends Model
{
    use BelongsToTenants;
    use HashedId;
    //
    protected $fillable = [
        'client_id',
        'invoice_number',
        'purchase_order',
        'invoice_note',
        'invoice_status',
        'invoice_total',
        'invoice_type',
        'sub_total',
        'balance_due',
        'due_date',
        'invoice_type',
        'user_id',
    ];

    protected $hidden = [
        'user_id'
    ];

    public function items()
    {
        return $this->belongsToMany('App\LineItem', 'invoice_items', 'invoice_id', 'item_id');
    }

    public function client()
    {
        return $this->belongsTo('App\Client');
    }

}

我曾尝试从控制器执行此操作,但它感觉更像是黑客,而不是正确的操作方法,而且我仍然无法使用$invoice->attach($lineItem)$invoice->items

I have tried doing this from a controller but it feels more like a hack than the right way to do it and I still lose the ability to use things like $invoice->attach($lineItem) or $invoice->items

//Currently I have to unhash the ids in order to save them as a pivot
$hashIds = new \Hashids\Hashids(env('APP_KEY'), 10);
$invoiceId = $hashIds->decode($request->invoice_id)[0];
$lineItemId = $hashIds->decode($request->item_id)[0];

//Should have been able to use $invoice->attach($lineItemId)
DB::table('invoice_items')->insert(
  ['invoice_id' => $invoiceId, 'item_id' => $lineItemId]
);

如何在仍然使用散列我的ID的特征的同时继续使用控制器中的$invoice->attach($lineItem)$invoice->items?

How can I continue to use $invoice->attach($lineItem) or $invoice->items from controllers while still using the trait that hashes my ids?

推荐答案

我将特征重写如下(假设您使用的是PHP 5.6或更高版本):

I've re-written the trait as follows (this assumes you're using PHP 5.6 or above):

<?php 

namespace App\Traits;

use Hashids\Hashids;
use Illuminate\Database\Eloquent\Builder;

trait HashedId
{
    /**
     * Get model ID attribute encoded to hash ID.
     *
     * @return string
     */
    public function getHashIdAttribute()
    {
        $hashIds = new Hashids(env('APP_KEY'), 10);
        return $hashIds->encode($this->getKey());
    }

    /**
     * Restrict query scope to find model by encoded hash ID.
     * 
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @param  integer  $id
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeHashId(Builder $query, $id)
    {
        $hashIds = new Hashids(env('APP_KEY'), 10);
        $id = $hashIds->decode($id)[0];

        return $query->where('id', $id);
    }

    /**
     * Restrict query scope to find models by encoded hash IDs.
     * 
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @param  array  $ids
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeHashIds(Builder $query, ...$ids)
    {
        $hashIds = new Hashids(env('APP_KEY'), 10);

        $ids = array_map(function ($id) use ($hashIds) {
            return $hashIds->decode($id)[0];
        }, $ids);

        return $query->whereIn('id', $ids);
    }
}

您可能会注意到,我已将访问器getIdAttribute()重命名为getHashIdAttribute().因此,您现在可以通过调用$model->hash_id而不是$model->id来获取模型实例的哈希ID.

You may notice that I've renamed the accessor, getIdAttribute() to getHashIdAttribute(). You can therefore now get the hash ID of a model instance by calling $model->hash_id instead of $model->id.

这是我认为您的问题所在,因为Laravel期望$model->id返回一个整数键,而它本来会获取哈希ID.

This is where I think your problem was, because Laravel was expecting an integer key to be returned by $model->id, whereas it would have been getting the hash ID instead.

在实施上述更改后,如果仍然出现错误,您可以显示具体错误是什么吗?

If after implementing the changes above you're still getting an error, can you show what the specific error is?

这篇关于L5如何使用具有哈希ID但保留支点功能的特征的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆