Laravel - 存储常见模型功能的地方&如何从控制器访问它们?

时间:2017-01-16 04:38:29

标签: php laravel model-view-controller model extends

我的模型的大多数使用了许多功能 所以将它们集中存储而不是重复代码是有意义的。

例如,我有一个函数可以从我需要的表中找到一个随机行:

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'使用正确的模型表?

2 个答案:

答案 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)

您可以同时使用inheritancetrait。但强烈建议您使用Eloquent模型而不是DB::table()。原因是如果某个表名更改,您必须在任何地方更改它。使用Eloquent,您只需在模型中提及一次表名。

protected $table = 'new_table_name'

使用继承

按以下方式构建BaseModelclass

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
}

使用特质

按如下方式构建您的traitclass

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();
    }
}