在运行时更新表名称不起作用 - laravel Eloquent ORM

时间:2014-12-11 07:52:04

标签: laravel-4 model eloquent

这是我的模特:

class Product extends \GlobalModel {
    protected $table = 'product';
}

我想在运行时更新表名 oops_product 而不是产品

我发现 getTable(); 从模型中获取表名并且工作正常:

$tableName = with(new Product)->getTable();

但是当我根据GitHub解决方案使用 setTable(); 设置表名时,它不会更新表名。

with(new Product)->setTable("oops_produdct");

有什么不对吗?

帮助将不胜感激。

编辑:

$product = new Product(); 
$product->getTable(); // output: product 
$product->setTable("oops_product"); 
$product->getTable(); // output: oops_product 

现在我跑这个

$product->all(); 

执行

"select * from product" 

而不是

"select * from oops_product"

5 个答案:

答案 0 :(得分:14)

all()是一种静态方法,它使用全新的实例并在其上调用get()

所以你需要的只是使用正确的方法:

$product = new Product;
$product->getTable(); // products
$product->setTable('oooops');
$product->get(); // select * from oooops
$product->first(); // select * from oooops limit 1
etc...

避免使用静态Eloquent方法,因为它们显然会创建具有默认table属性的新实例。

答案 1 :(得分:4)

接受的答案的问题是,修改检索到的模型实例以及稍后保存它不会起作用。请参阅上面的评论。

以下特性允许在水合作用期间传递表名。

trait BindsDynamically
{
    protected $connection = null;
    protected $table = null;

    public function bind(string $connection, string $table)
    {
        $this->setConnection($connection);
        $this->setTable($table);
    }

    public function newInstance($attributes = [], $exists = false)
    {
        // Overridden in order to allow for late table binding.

        $model = parent::newInstance($attributes, $exists);
        $model->setTable($this->table);

        return $model;
    }

}

以下是如何使用它:

class Product extends Model
{
    use BindsDynamically;
}

应用于接受的答案:

$product = new Product;
$product->getTable(); // products
$product->bind('connection', 'oooops');
$product->get(); // select * from oooops
$product->first(); // select * from oooops limit 1
etc...
$product->myTestProp = 'test;
$product->save(); // now saves into oooops

答案 2 :(得分:0)

找到一种执行此操作的方法: 将其插入到Model类中,并根据您的逻辑进行自定义。

    public function companies(){
      $instance = Community::of($this->community); //create instance
      $foreignKey = 'id';
      $localKey = 'foreign_id';
      $tableName = $instance->getTable(); //or any logic of yours
      //Here you can dynamically choose the table name, taken from the "HasRelationships.php" File of Laravel
      return $this->newHasMany(
          $instance->newQuery(), $this, $tableName.'.'.$foreignKey,   $localKey
      );
    }

答案 3 :(得分:0)

这也应该适用于静态方法(仅在5.7上进行测试)

use Illuminate\Database\Eloquent\Model;

function makeModel($table)
{
    $model = new class extends Model
    {
        public static $entryTable;

        public function setTable($table)
        {
            $this->table = static::$entryTable = $table;
        }

        public static function __callStatic($method, $parameters)
        {
            $static = (new static);
            $static->setTable($static::$entryTable);

            return $static->$method(...$parameters);
        }
    };
    $model->setTable($table);

    return $model;
}

答案 4 :(得分:0)

我需要根据我的请求更改表名(我的表将根据我的请求添加前缀)。我所做的是将Model类扩展为MyModel,然后覆盖了构造方法,将基于我的请求的表名与我提供的模型的默认表名结合在一起。

class MyModel extends Model
{

  public function __construct(array $attributes = [])
  {
      parent::__construct($attributes);
      $this->setTable(Config::get('tablePrefix').$this->getTable());
  }
}

您应该将Config表前缀替换为您的方法。

然后在我的模型中,我扩展了MyModel,包括测试中的静态调用在内,一切都很好。

class Category extends MyModel
{

  protected $table = "categories";
}

因此,随着我的请求发生变化,我更改了我提供的配置,并且可以使用不同的表名,例如a__categories,b__categories,并且一切都很好,包括静态调用,关系和保存到数据库。