在下面的Laravel 5模型中,findByIdAndCourseOrFail
方法应该是静态的吗?
class Section extends Model {
//should this method be static?
public function findByIdAndCourseOrFail($id, $courseId)
{
$result = $this->where('id', $id)->where('course_id', $courseId)->first();
if (!is_null($result))
{
return $result;
}
throw (new ModelNotFoundException())->setModel(Section::class);
}
}
使用控制器:
class SectionsController extends Controller {
protected $sections;
public function __construct(Section $section)
{
$this->sections = $section;
}
public function foo($id, $courseId) //illustration only
{
$section = $this->sections->findOrFail($id);
$section = $this->sections->findByIdAndCourseOrFail($id, $courseId);
//would need to be non-static
$section = Section::findByIdAndCourseOrFail($id, $courseId);
//weird when compared with find above
}
一方面,我们没有采取剖面实例[见注释]。另一方面,在通过Laravel's service container进行自动依赖注入的控制器中,我们将对一个实例执行操作:$sections = $this->sections-> findByIdAndCourseOrFail(7,3);
并且我的IDE(PhpStorm)会在Static
时发出警告。
[注意]:这个评论可能是对Laravel Models如何运作的误解。对我来说,我希望find()
,findOrFail()
是Class方法,因此静态而不是find方法返回的实例。
答案 0 :(得分:1)
class Section extends Model {
public static function findByIdAndCourseOrFail($id, $courseId)
{
$result = self::where('id', $id)->where('course_id', $courseId)->first();
if (!is_null($result))
{
return $result;
}
throw (new ModelNotFoundException())->setModel(Section::class);
}
}
答案 1 :(得分:1)
我个人认为这是一个静态的方法,我不确定是否有“正确”的答案,但任何一方都可以。我在脑海中将它们分开的方式是,如果我正在对模型的实例做一些事情,那么我将它作为普通的公共函数。如果我正在对集合做一些事情,我会使用静态。例如:
$person = new Person();
$person->setAdmin(true);
$person->save();
// OR
$admins = Person::getAdmins();
在第一个例子中,我们有一个Person
的特定实例,我们正在操作它,所有代码都只是操纵该特定实例。在第二个示例中,我们对Person
的整个集合进行操作,并且我们希望返回一组对象。
在您的情况下,您必须启动Section
的实例才能使用非静态公共方法,如下所示:
$section = new Section();
$foundSection = $section->findByIdAndCourseOrFail(7,3);
所以$section
成为一个永远不会真正使用的临时变量。另一方面,如果你把它设为静态,你就可以不必这样做就可以调用它。
$section = Section::findByIdAndCourseOrFail(7,3);
希望这是有道理的。
答案 2 :(得分:1)
我不确定local scopes是否应该像这样使用。但它在laravel 5.2上适用于我:
public function scopeFindByIdAndCourseOrFail($query, $id, $courseId)
{
$result = $query->where('id', $id)->where('course_id', $courseId)->first();
if (!is_null($result))
{
return $result;
}
throw (new ModelNotFoundException())->setModel(Section::class);
}
在控制器中,您可以双向使用:
$section = Section::findByIdAndCourseOrFail($id, $courseId);
或
$model = new Section();
$section = $model->findByIdAndCourseOrFail($id, $courseId);