Я добавил хэши к своим идентификаторам, используя черту. Однако теперь я больше не могу использовать attach () или отношения.
Например, эти отношения больше не работают на мой взгляд:
@foreach ($invoice->items as $item)
{{ $item->item }}
@endforeach
Вот черта, которая хеширует идентификатор для меня
<?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
из контроллеров, все еще используя черту, которая хэширует мои идентификаторы?
Я переписал эту черту следующим образом (предполагается, что вы используете 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
,
Вот где я думаю, что ваша проблема была, потому что Laravel ожидал, что целочисленный ключ будет возвращен $model->id
тогда как вместо этого он получал бы хэш-идентификатор.
Если после внесения вышеуказанных изменений вы все еще получаете ошибку, можете ли вы показать, в чем конкретно заключается ошибка?
Так же, как вы прокомментировали, вы не можете использовать attach, потому что id хешируется, потому что getIdAttribute. Я хотел бы предложить вам использовать getOriginal ().
Например,
$invoice->attach($lineItem->getOriginal()['id']);
Я думаю, что это может быть единственным способом приложить это.