最佳实践-Laravel控制器雄辩合并
我的供应商模型上有一个作用域,它返回的结果为最佳实践-Laravel控制器雄辩合并,laravel,eloquent,controller,Laravel,Eloquent,Controller,我的供应商模型上有一个作用域,它返回的结果为active=true 这在创建新条目时非常有效,因为我只希望用户看到活跃的供应商 当前条目可能有一个不活跃的供应商;编辑时,我希望看到所有活动供应商,加上当前供应商(如果是非活动供应商) 我的控制器中有以下代码: $suppliers=Supplier::active()->get(); 如果(!$suppliers->contains('id',$record->supplier->id)) { $suppliers->add(供应商::查找($r
active=true
这在创建新条目时非常有效,因为我只希望用户看到活跃的供应商
当前条目可能有一个不活跃的供应商;编辑时,我希望看到所有活动供应商,加上当前供应商(如果是非活动供应商)
我的控制器中有以下代码:
$suppliers=Supplier::active()->get();
如果(!$suppliers->contains('id',$record->supplier->id))
{
$suppliers->add(供应商::查找($record->Supplier->id));
}
两个问题:这是正确的方法吗?这个代码应该在我的控制器中还是应该在其他地方?(可能是一个范围,但我不知道如何编写代码)
编辑: 谢谢你们的帮助。我应用了每个答案中的建议,并将代码重构到一个新的范围:
public函数范围包括($query,Model$Model=null)
{
$query->where('active',1);
如果($model&&!$model->supplier->active)
{
$query->orWhere('id',$model->supplier->id);
}
}
您所编写的内容将起作用,但是如果集合很大,则Collection::contains
函数可能会非常慢
由于您有id,我可能会进行以下更改:
$suppliers = Supplier::active()->get();
$supplier = Supplier::find($record->supplier->id);
if (!$supplier->active) {
$suppliers->add($supplier);
}
当然,这样做的缺点是,可能会对数据库进行不必要的查询
因此,你必须考虑:
记录的供应商更可能是活跃的还是不活跃的
- 活动供应商集合的大小是否足够大,足以证明对数据库的另一次调用(可能被浪费)是合理的
至于第二个问题,如果您在应用程序的这一部分中只需要这组特定的供应商,那么控制器是编写此代码的好地方 但是,如果您在应用程序的其他部分需要这组特定的供应商,您可能应该将此代码移到其他地方。在这种情况下,在相关模型(无论
$record
是什么类型)上创建一个返回该模型的供应商集的函数可能是有意义的。比如:
public function getSuppliers()
{
$suppliers = Supplier::active()->get();
$supplier = $this->supplier;
if (!$supplier->active) {
$suppliers->add($supplier);
}
return $suppliers;
}
我看到了@Vince对第一个问题的回答,我同意他的看法。 关于第二个问题: 在供应商模型中写入范围,如下所示: 为了获得良好的实践,您需要在“App\services\SupplierService.php”等服务中编写逻辑部分。然后写下你想要的函数: 在SupplierController的构造函数中,插入该服务的实例并使用该函数,例如: 正如您所看到的,稍后您将不需要更改控制器中的任何内容。例如,如果您需要更改供应商选择查询,您只需更改服务中的某些内容即可。这种方式将使代码块分离并缩短。 这种模式的另一个意义是:您不需要从控制器访问模型。所有与模型相关的逻辑都将在服务中实现。
对于其他项目,您只能获取服务或控制器,并以不同的方式实现另一部分。但在这种情况下,如果控制器中有所有代码,这将阻止您获取必要代码的部分,因为您可能不记得每个块都在做什么…您可以在查询中添加一个
where
子句来查找该id
$suppliers=Supplier::active()->或where('id',$record->Supplier->id)->get();
您可以通过将“id”作为参数传递,潜在地将其滑入活动的范围
public函数scopeActive($query,$id=null)
{
$query->where('active',true);
如果($id){
$query->orWhere('id',$id);
}
}
供应商::活动($record->Supplier->id)->get();
或者制作另一个这样做的示波器。这是一个很好的答案,谢谢。你对我问题的第二部分有什么想法吗?啊,我错过了第二部分。我会更新我的答案。
public function scopeActive($query){
$query->where('active', 1); // for boolean type
}
public function activeSuppliersWithCurrent($record) {
$suppliers = Supplier::active()->get();
$supplier = Supplier::find($record->supplier->id);
if (!$supplier->active) {
$suppliers->add($supplier);
}
}
use App\Servives\SupplierService;
protected $supplierService = null;
public function __construct(SupplierService $supplierService) {
$this->supplierService = $supplierService;
}
public function getActiveSuppliersWithCurrent(...) {
$result = $this->supplierService->activeSuppliersWithCurrent($record);
}