Eloquent - 可以在查询时动态创建关系

Posted

技术标签:

【中文标题】Eloquent - 可以在查询时动态创建关系【英文标题】:Eloquent - Possibility to create relationship dynamically on query 【发布时间】:2020-01-15 05:43:31 【问题描述】:

我有 2 款优惠券和产品。

一张优惠券可以有多个产品。

关键是它可能是一些不同的组合(例如productA + productB,或productA OR productB等......)

所以我所做的不是在优惠券和产品之间建立关系,而是将产品 ID 像字符串一样存储在我的字段中(例如:1+2,这意味着当购买这两种产品时,此优惠券可用)。

我承认这可能不是我最好的主意......

现在我的问题是我需要根据产品类别(我的产品模型中的一个字段)对我的优惠券提出请求。 是否可以进行这样的查询(我最初认为我可以使用 Coupon 上的范围来实现它,但我无法做到),或者我的数据库结构这样太糟糕了,我应该更新它并使用多态关系(我也不知道该怎么做)。

这是我的优惠券模型:

class Coupon extends Model 
use Traits\Uuids;


protected static function boot()

    parent::boot();

    static::addGlobalScope(function ($query) 
        $query->hasProductCategory();
    );


/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'name', 
    'description',
    'products_id',
    'client_id',
    'facial_value',
    'image',
    'is_valid',
    'begin_date',
    'end_date',
    'use_case'
];

/**
 * The attributes excluded from the model's JSON form.
 *
 * @var array
 */
protected $hidden = [
    'created_at', 
    'updated_at'
];


/**
 * Indicates if the IDs are auto-incrementing.
 *
 * @var bool
 */
public $incrementing = false;

/**
 * We define our default primary key.
 *
 * @var string
 */
protected $primaryKey = 'uuid';



/** 
* Define if coupon has multiple products or just one
* return bool
*/
public function scopeIsSingleProduct():bool

    $aProduct = explode("+", $this->products);

    return count($aProduct) > 1 ? false : true;


public function client()

    return $this->belongsTo(Client::class, 'client_id');


public function cart()

    return $this->hasMany(Cart::class);


public function campaign()

    return $this->hasMany(Campaign::class);

这是产品的模型

class Product extends Model 
protected $fillable = [
    'name', 
    'ean',
    'category_id',
    'client_id',
    'init_price'
];

/**
 * The attributes excluded from the model's JSON form.
 *
 * @var array
 */
protected $hidden = [
    'created_at', 
    'updated_at'
];

public function client()

    return $this->belongsTo(Client::class, 'client_id');



public function category()

    return $this->belongsTo(CategoryProduct::class, 'category_id');


public function productsId()

    return preg_split( "/(\+|\|)/", $this->products);

感谢您的帮助。

【问题讨论】:

您只需要使用多对多关系。没有多少关系 其实我的问题是我没有建立关系,我只是想知道我是否可以在查询中动态建立它。 更新了我的帖子以添加两个模型。 productcoupon 之间存在多对多关系的问题是什么?为什么要使用字符串字段来保存多个 id,因为您可以拥有一个表,其中每个 id 都有一个条目(与数据透视表的多对多关系coupon_product 如上所述,我使用的是字符串字段,因为我没有简单的关系,我需要以某种方式存储这种复杂性。优惠券可以与多种组合一起使用(例如产品 A 或产品 B,但也可能是产品 A + 产品 B),我认为这种方式更容易管理这些 AND / OR 差异。 【参考方案1】:

您应该重新考虑您的数据库结构。

优惠券:产品是多对多关系。

这意味着它们将存储在数据透视表中,您可以根据需要进行查询。此外,如果它可以帮助您更轻松地编写查询,您可以为数据透视表创建一个模型。

【讨论】:

好的,我希望有一种方法可以模拟关系并保持我的实际结构。但我明白这有多奇怪。在为此苦苦挣扎之后,我认为我确实必须更新我的数据库结构并使用数据透视表。我必须考虑一下它的结构,因为它不是“简单”的多对多关系,因为我必须管理几种产品和优惠券之间的不同类型的关系。感谢您的回答。

以上是关于Eloquent - 可以在查询时动态创建关系的主要内容,如果未能解决你的问题,请参考以下文章

创建动态的 Eloquent 类 laravel

Laravel 动态关系 - 在急切加载时访问模型属性

Laravel Eloquent ORM 关系命名约定

在使用 tinker CLI 时,Laravel 如何在 Eloquent 模型上查找和显示动态属性?

Laravel Eloquent ORM查询关系里面的关系

Laravel eloquent 检查不存在的多对多关系