这是我的模特:
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"
答案 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,并且一切都很好,包括静态调用,关系和保存到数据库。