每当调用模型作用域时,是否可以向我的模型添加属性?
例如,在我的控制器中,我想调用一个范围以附加那些动态属性,例如:
$Media_query = OutDoorMedia::query();
$Media_query->orderby('created_at', 'desc');
$Media_query->PreviouslyOrdered();
$Media = $Media_query->get();
在我的模型中,我想做类似的事情:
class OutDoorMedia extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'id',
'user_id',
'address',
'location',
'media_type',
];
}
class scopePreviouslyOrdered extends OutDoorMedia
{
public $appends = ['previously_ordered'];
public function getPreviouslyOrderedAttribute()
{
if ($this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id')->Where(function ($query) {
$query->where('status', MEDIA_ORDER_CHECKOUT_STATUS)
->orWhere('status', STATUS_TO_PAY);
})->exists()) {
return true;
} else {
return false;
}
}
}
但是它不起作用,我知道这是错误的,如何实现呢?
答案 0 :(得分:2)
我在@apokryfos的帮助下解决了这个问题,但做了一些调整。希望这样减少浪费别人的时间。
我没有通过雄辩的魔术方法将所述属性附加到模型上,而是在模型上附加了属性:
barplot(t(as.matrix(hos)),
main = 'Mortality Rate in Cooper Green Mercy Hospital',
xlab = 'Illness', ylab = 'Mortality Rate',
names.arg = names(hos),
beside = TRUE,
space = c(0.05, 0))
在模型中正如apokryfos所说的,我已经使用了这两种方法:
$Media_query = OutDoorMedia::query();
$Media_query->orderby('created_at', 'desc');
$Media = $Media_query->get()->each(function ($items) {
$items->append('previously_ordered');//add this attribute to all records which has the condition
});
但是我不需要这种方法,我不得不将其从模型中删除,因为如果它存在于模型中,它将自动追加到模型中:
public function PreviousOrders() {
return $this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id');
}
public function getPreviouslyOrderedAttribute() {
return $this->PreviousOrders()->exists();
}
答案 1 :(得分:1)
我认为对作用域的工作方式存在误解。范围基本上就像是对模型的快捷查询。您正在使用它来测试关系的存在,但是有一种更好的方法可以使用whereHas
以下是通过关系实现此目的的方法:
class OutDoorMedia extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'id',
'user_id',
'address',
'location',
'media_type',
];
public function previousOrders() {
return $this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id');
}
public function getPreviouslyOrderedAttribute() {
return $this->previousOrders()->exists();
}
}
然后您只需做:
$Media_query = OutDoorMedia::whereHas('previousOrders')
->orderby('created_at', 'desc');
如果您将动态属性自动附加到模型上,则可以将以下内容添加到模型中:
public $appends = [ 'previously_ordered' ];
我想,如果您想要两全其美,可以做到:
class OutdoorMediaWithPreviouslyOrdered extends OutDoorMedia {
public $appends = [ 'previously_ordered' ];
}
然后,当您需要附加模型时,可以使用:
$Media_query = OutdoorMediaWithPreviouslyOrdered ::orderby('created_at', 'desc');