L5如何使用哈希id但保持枢轴功能的特征

时间:2017-02-20 04:51:29

标签: php laravel laravel-5 laravel-5.3

我使用特征为我的ID添加了哈希值。但是,通过这样做,我现在不能再使用attach()或关系。

例如,此关系在我的视图中不再有效:

@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

等内容
//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]
);

如何继续使用来自控制器的$invoice->attach($lineItem)$invoice->items,同时仍然使用隐藏我的ID的特征?

2 个答案:

答案 0 :(得分:1)

就像你评论的那样,你不能使用attach,因为id是getIdAttribute的散列cos。我建议你使用getOriginal()。

例如,

$invoice->attach($lineItem->getOriginal()['id']);

我认为这可能是附加它的唯一方法。

答案 1 :(得分:1)

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

<?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。

这就是我认为你的问题所在,因为Laravel期望$model->id返回一个整数键,而它本来会得到哈希ID。

如果在执行上述更改后仍然出现错误,您是否可以显示具体错误?