我的模型的大多数使用了许多功能 所以将它们集中存储而不是重复代码是有意义的。
例如,我有一个函数可以从我需要的表中找到一个随机行:
function getRandomRow() {
$rowCount = DB::connection('mydatabasename')
->table('my_table_name')
->selectRaw("FLOOR(RAND() * COUNT(*)) AS offset")
->first();
$offset = $rowCount->offset;
$randomRow = DB::connection('mydatabasename')
->table('my_table_name')
->select()
->offset($offset)
->limit(1)
->first();
return $randomRow;
}
我已查看inheritance(扩展)和traits以及docs on polymorphic relations - 但不清楚哪个最有效以及如何在公共函数中访问表名(与正在使用的模型相关联)。
我的问题:
- 我在哪里放置此功能,以便所有型号都可以使用?
- 如何编写代码以便'my_table_name'
使用正确的模型表?
答案 0 :(得分:3)
我找到的最简单的解决方案是创建父模型/类 - 如this answer中针对不同的问题所述 - 对于当前示例,我们将其称为BaseModel
。
对于Laravel,它与其他模型一起存储,直接存储在App
目录
...在我的情况下,父模型/类可以是abstract
,因为它不需要拥有它自己的表(也意味着BaseModel
函数只能通过儿童模型访问):
namespace App;
use Illuminate\Database\Eloquent\Model;
abstract class BaseModel extends Model
{
// ...put common model functions here
}
让这个工作的技巧(BaseModel
函数需要访问子模型的表)是:
- 让每个儿童模特/班级extend
成为BaseModel
班级
- 确保在所有子模型中定义$table
- 如上所述here:
class MyFunkyModel extends BaseModel
{
protected $table = 'funktown';
// ...put child specific functions here
}
这意味着可以在$this->table
抽象父类中使用BaseModel
来引用子模型/类的指定$table
:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
abstract class BaseModel extends Model
{
function getRandomRow() {
$rowCount = DB::connection('mydatabasename')
->table($this->table)
->selectRaw("FLOOR(RAND() * COUNT(*)) AS offset")
->first();
$offset = $rowCount->offset;
$profileRow = DB::connection('mydatabasename')
->table($this->table)
->select()
->offset($offset)
->limit(1)
->first();
return $profileRow;
}
}
现在,您可以通过子模型从控制器访问存储在BaseModel
中的任何函数:
namespace App\Http\Controllers;
use App\MyFunkyModel;
use App\MySeriousModel;
use App\MyHappyModel;
class MyController extends Controller
{
public function getRandomName($type){
switch ($type) {
case 'funky':
$modelFunky = new MyFunkyModel;
$funkyRow = $modelFunky->getRandomRow();
$randomName = $funkyRow->funky_name_column;
break;
case 'serious':
$modelSerious = new MySeriousModel;
$seriousRow = $modelSerious->getRandomRow();
$randomName = $seriousRow->serious_name_column;
break;
case 'happy':
$modelHappy = new MyHappyModel;
$happyRow = $modelHappy->getRandomRow();
$randomName = $happyRow->happy_name_column;
break;
return $randomName;
}
}
答案 1 :(得分:3)
您可以同时使用inheritance
和trait
。但强烈建议您使用Eloquent
模型而不是DB::table()
。原因是如果某个表名更改,您必须在任何地方更改它。使用Eloquent
,您只需在模型中提及一次表名。
protected $table = 'new_table_name'
使用继承
按以下方式构建BaseModel
和class
。
class BaseModel extends Model {
public static function getRandomRow()
{
$rowCount = self::selectRaw("FLOOR(RAND() * COUNT(*)) AS offset")
->first();
$offset = $rowCount->offset;
$randomRow = self::select()
->offset($offset)
->limit(1)
->first();
return $randomRow;
}
}
class YourModel extends BaseModel {
// getRandomRow() available here
}
使用特质
按如下方式构建您的trait
和class
。
trait BaseTrait {
public static function getRandomRow()
{
$rowCount = self::selectRaw("FLOOR(RAND() * COUNT(*)) AS offset")
->first();
$offset = $rowCount->offset;
$randomRow = self::select()
->offset($offset)
->limit(1)
->first();
return $randomRow;
}
}
class YourClass {
use BaseTrait;
// getRandomRow() available here
}
无论哪种方式,您都可以访问您的方法,如
class yourController {
public function youMethod()
{
$rows = YourModel::getRandomRow();
}
}