是否有人知道在关系中包含orWhere以允许多个值与键匹配的方法?
一个例子是我们有一个产品型号,而产品可以是另一个产品(parent_id)的子产品,我们想要从产品和父产品中提取产品。
对于我们可能想要的关系:
public function items()
{
return $this->hasMany(Item::class)
->orWhere('product_id', $this->parent_id);
}
上面的示例适用于将product_id与id和parent_id进行匹配,但是当我们尝试使用该关系执行更多操作时会快速转换,因为它不会嵌套where调用。
所以SQL将是:SELECT * FROM items WHERE product_id = x OR product_id = y
因此,当我们执行$product->items()->where('value', '>', 1);
之类的操作时,它会破坏关系,因为它会:
SELECT * FROM items WHERE product_id = x OR product_id = y AND value > 1
而不是:
SELECT * FROM items WHERE (product_id = x OR product_id = y) AND value > 1
我们有一个解决方法,没有使用Eloquent关系(合并两个集合),但我想尽可能利用关系方法。
答案 0 :(得分:1)
正如@Danny评论的那样,它是对hasMany
关系的滥用,合并$product->items
和$product->parent->items
关系会更合适。但是,如果您需要解决方法,可以手动创建关系:
public function items() // I would rather create another method for this specific relationship
{
$foreignKey = $this->getForeignKey();
$instance = new Item;
$localKey = $this->getKeyName();
$hasMany = new \Illuminate\Database\Eloquent\Relations\HasMany(
$instance->newQuery()->whereRaw('(true'),
$this,
$instance->getTable().'.'.$foreignKey,
$localKey
);
return $hasMany->orwhereRaw('product_id = ? )', [$this->parent_id]);
}
所以你的查询将是
SELECT * FROM items WHERE (true and product_id = x OR product_id = y) AND value > 1
我无法弄清楚如何删除无用的true
条件,Laravel不断在场景后添加and
关键字。