首先我必须说我试图找到解决方案,但我没有。
基本问题:
$Br = new BrandTop;
dd( $Br->limit(10)->get() ); // Will return 10 rows
Run Code Online (Sandbox Code Playgroud)
和
$Br = new BrandTop;
$Br->limit(10);
dd( $Br->get() ); // Will return all rows.
Run Code Online (Sandbox Code Playgroud)
那么,基本问题是——为什么?如何为模型设置一些限制,但仍然可以使用它,例如设置(或不设置)某些位置或顺序取决于其他变量。
高级问题:
我想像这样使用模型:
class BrandTop extends Model
{
public function withBrand() {
return $this->leftJoin('brand', 'brand.id' , '=', 'brandtop.brand_id');
}
public function forType($type) // there is much more conditions for type
{
return $this->where(['type' => $type]);
}
// main function
public function forSunglasses($limit = 0, $logo = false)
{
if ($logo)
$this->where(['menu_logo' => 1])->orderBy('total_sales', 'desc');
if ($limit)
$this->limit($limit);
return $this->forType('sunglasses')->withBrand();
// But there goes Error, because forType() return Builder object, and it has no withBrand() method
}
}
Run Code Online (Sandbox Code Playgroud)
因此,条件要多得多,并且在单独的方法中设置所有条件要容易得多。但如何呢?
Model
这里需要理解的是对象和底层(查询生成器)对象之间的区别Builder
。
该语句$Br = new BrandTop;
将创建 a 的新实例Model
,并将其分配给$Br
变量。接下来,该$Br->limit(10)
语句将为brand_tops 表创建一个新的Builder
对象实例,并应用 10 个限制。
在您的第一个示例中,通过执行$Br->limit(10)->get()
,您正在调用get()
应用Builder
了您的限制的 。
在第二个示例中,您的个人$Br->limit(10)
创建了新Builder
实例,但从未将其用于任何用途。下一条语句$Br->get()
创建另一个Builder
没有任何约束的新实例,因此它检索所有记录。
为了能够构建查询,您需要将Builder
实例分配给变量,并在最终调用之前继续修改该实例get()
。例如,要使第二个示例正常工作:
$query = BrandTop::query();
$query->limit(10);
$query->where(/*conditions*/);
dd($query->get());
Run Code Online (Sandbox Code Playgroud)
关于问题的第二部分,您可能想研究查询范围。
class BrandTop extends Model
{
// renamed to "JoinBrand" instead of "WithBrand", as "with" would imply
// an eager loaded relationship vs a joined table
public function scopeJoinBrand($query)
{
return $query->leftJoin('brand', 'brand.id' , '=', 'brandtop.brand_id');
}
// got rid of "for" prefix
public function scopeType($query, $type)
{
return $query->where('type', $type);
}
// got rid of "for" prefix
public function scopeSunglasses($query, $limit = 0, $logo = false)
{
if ($logo)
$query->where(['menu_logo' => 1])->orderBy('total_sales', 'desc');
if ($limit)
$query->limit($limit);
return $query->type('sunglasses')->joinBrand();
}
}
Run Code Online (Sandbox Code Playgroud)
使用上述模型,您的代码将类似于:
dd(BrandTop::sunglasses()->get());
// or, more verbosely:
$query = BrandTop::query();
$query->sunglasses(); // $query already an object, no need to reassign it to itself
dd($query->get());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1921 次 |
最近记录: |