如何用逗号分隔的 id 模仿 Eloquent 关系 [英] How to mimic Eloquent relationship with comma separated ids

查看:29
本文介绍了如何用逗号分隔的 id 模仿 Eloquent 关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个表,订单和层.在我的订单表中,我在 layer_id 中保存了一个数组,我已将其设置为 varchar.我先爆炸它,然后显示记录.我想要做的是显示来自图层表的记录,例如来自 layer_name 列的名称.我也设定了他们的关系.如有任何建议,我将不胜感激.

我的控制器:

公共函数getCheckout(){$orders = Order::get();return View::make('checkout')->with('orders', $orders);}

我的观点:

@forelse($orders as $order)<div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title">{{ $order->style_id }}</h3>

<div class="panel-body"><p>您选择的图层</p><table class="table"><tr><td>ID</td>@foreach(explode(',', $order->layer_id) as $layer)<td>{{ $layer }}</td>@endforeach</tr>

<div class="panel-footer"><button class="btn btn-primary">确认</button></div>

@空的<p>没有可显示的内容</p>@endforelse

我的模特

Class Order extends Eloquent {公共功能层(){返回 $this->belongsTo('Layer', 'layer_id');}}

解决方案

我的第一个建议是规范化你的数据库.在 Eloquent ORM 的上下文中,您不能为此使用内置关系.

但是,出于好奇,您应该这样做:

通过以下设置,您可以:

//1. 使用layers之类的eloquent动态属性$order->layers;//层模型的集合//2. 调用查询只获取一次图层$order->layers;//查询并设置关系"//... 更多代码$order->layers;//无查询,访问关系//3. 进一步的查询层就像你用关系作为方法:$order->layers()->where(..)->orderBy(..)->...->get();//4. 手动关联图层,提供数组或字符串:$order->layer_ids = '1,5,15';$order->layer_ids = [1,5,15];

但你不能:

//1. Eager/Lazy 加载多个订单的图层$orders = Order::with('layers')->get();//行不通//2. 使用任何关系方法进行关联/保存/附加等.$order->layers()->associate(..);//行不通

但这里是您可以做的(我建议将 layer_id 重命名为 layer_ids,这样就不言自明了,我的示例涵盖了该更改):

/*** 模仿 Eloquent 动态属性的访问器.** @return IlluminateDatabaseEloquentCollection*/公共函数 getLayersAttribute(){if (!$this->relationLoaded('layers')) {$layers = Layer::whereIn('id', $this->layer_ids)->get();$this->setRelation('layers', $layers);}返回 $this->getRelation('layers');}/*** 访问层关系查询.** @return IlluminateDatabaseEloquentBuilder*/公共功能层(){return Layer::whereIn('id', $this->layer_ids);}/*** layer_ids 属性的访问器.** @return 数组*/公共函数 getLayerIdsAttribute($commaSeparatedIds){返回explode(',', $commaSeparatedIds);}/*** layer_ids 属性的修改器.** @param 数组|字符串 $ids* @return 无效*/公共函数 setLayersIdsAttribute($ids){$this->attributes['layers_ids'] = is_string($ids) ?$ids : 内爆(',', $ids);}

<小时>

当然,您可以在您的视图中简单地执行此操作.它符合您当前的代码,但显然与我的建议相去甚远;)

@foreach (Layer::whereIn('id',explode(',', $order->layer_id))->get() as $layer){{ $layer->whatever }}

I have two tables, orders and layers. In my orders table i save an array in layer_id which i have set it to varchar. I explode it first and i display the records. What i wanna do is to display the records from layers table , for example names from layer_name columns . I have also set their relationships . I would appreciate any suggestions.

My controller:

public function getCheckout(){
    $orders = Order::get();
    return View::make('checkout')->with('orders', $orders);
}

My view:

@forelse($orders as $order)

<div class="panel panel-default">
    <div class="panel-heading">
        <h3 class="panel-title">{{ $order->style_id }}</h3>
    </div>
    <div class="panel-body">
    <p>Layers you chose</p>

    <table class="table">
        <tr>
        <td>ID</td>
        @foreach(explode(',', $order->layer_id) as $layer) 
            <td>{{ $layer }}</td>
        @endforeach
        </tr>

    </table>
</div>
    <div class="panel-footer"><button class="btn btn-primary">Confirm</button></div>
</div>

@empty

<p>Nothing to display</p>

@endforelse

My Model

Class Order extends Eloquent {
    public function layer() {
        return $this->belongsTo('Layer', 'layer_id');
    }
}

解决方案

My first suggestion would be normalize your db. In the context of Eloquent ORM you cannot use built-in relationships for this.

However for the sake of curiosity, here's what you should do:

With below setup you can:

// 1. Use layers like eloquent dynamic property
$order->layers; // collection of Layer models

// 2. Call the query to fetch layers only once
$order->layers; // query and set 'relation'
// ... more code
$order->layers; // no query, accessing relation

// 3. Further query layers like you would with relationship as method:
$order->layers()->where(..)->orderBy(..)->...->get();

// 4. Associate layers manually providing either array or string:
$order->layer_ids = '1,5,15';
$order->layer_ids = [1,5,15];

But you can't:

// 1. Eager/Lazy load the layers for multiple orders
$orders = Order::with('layers')->get(); // WON'T WORK

// 2. Use any of the relationship methods for associating/saving/attaching etc.
$order->layers()->associate(..); // WON'T WORK

But here's what you can do (I suggest renaming layer_id to layer_ids so it is self-explanatory, and my example covers that change):

/**
 * Accessor that mimics Eloquent dynamic property.
 *
 * @return IlluminateDatabaseEloquentCollection
 */
public function getLayersAttribute()
{
    if (!$this->relationLoaded('layers')) {
        $layers = Layer::whereIn('id', $this->layer_ids)->get();

        $this->setRelation('layers', $layers);
    }

    return $this->getRelation('layers');
}

/**
 * Access layers relation query.
 *
 * @return IlluminateDatabaseEloquentBuilder
 */
public function layers()
{
    return Layer::whereIn('id', $this->layer_ids);
}

/**
 * Accessor for layer_ids property.
 *
 * @return array
 */
public function getLayerIdsAttribute($commaSeparatedIds)
{
    return explode(',', $commaSeparatedIds);
}

/**
 * Mutator for layer_ids property.
 *
 * @param  array|string $ids
 * @return void
 */
public function setLayersIdsAttribute($ids)
{
    $this->attributes['layers_ids'] = is_string($ids) ? $ids : implode(',', $ids);
}


edit: Of course you could do simply this in your view. It adheres to your current code, but obviously is far from what I suggest ;)

@foreach (Layer::whereIn('id', explode(',', $order->layer_id))->get() as $layer)
  {{ $layer->whatever }}

这篇关于如何用逗号分隔的 id 模仿 Eloquent 关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆