我使用的是Laravel 4,有两种型号:
class Asset extends \Eloquent {
public function products() {
return $this->belongsToMany('Product');
}
}
class Product extends \Eloquent {
public function assets() {
return $this->belongsToMany('Asset');
}
}
产品
上有标准的时间戳(在
处创建,在
处更新),我想在附加/分离资产时更新
产品
的在
处更新的字段。
我在
资产
模型上尝试了这一点:
class Asset extends \Eloquent {
public function products() {
return $this->belongsToMany('Product')->withTimestamps();
}
}
...但这什么也没做(显然)。编辑:显然这是为了更新数据透视表上的时间戳,而不是在关系自己的表上更新它们(即更新
assets_products.updated_at
,而不是products.updated_at
)。
然后我在
资产
模型上尝试了这一点:
class Asset extends \Eloquent {
protected $touches = [ 'products' ];
public function products() {
return $this->belongsToMany('Product');
}
}
…这是可行的,但随后破坏了我的种子,它调用
Asset::create([…])
因为显然Laravel试图调用-
PHP致命错误:在第1583行的/projectdir/vendor/laravel/framework/src/illighte/Database/Eloquent/Model.PHP中调用未定义的方法illighte\Database\Eloquent\Collection::touchOwners()
我用来添加/删除资产的代码如下:
Product::find( $validId )->assets()->attach( $anotherValidId );
Product::find( $validId )->assets()->detach( $anotherValidId );
我哪里做错了?
创建扩展雄辩的BaseModel
,对Create
方法进行简单调整:
BaseModel.php:
class BaseModel extends Eloquent {
/**
* Save a new model and return the instance, passing along the
* $options array to specify the behavior of 'timestamps' and 'touch'
*
* @param array $attributes
* @param array $options
* @return static
*/
public static function create(array $attributes, array $options = array())
{
$model = new static($attributes);
$model->save($options);
return $model;
}
}
让您的资产
和产品
模型(以及其他模型,如果需要)扩展基本模型
,而不是雄辩
,并设置$touchs
属性:
sset.php(和其他模式):
class Asset extends BaseModel {
protected $touches = [ 'products' ];
...
在播种机中,将create
的第二个参数设置为一个数组,该数组将'touch'
指定为false
:
Asset::create([...],['touch' => false])
Eloquent的保存()
方法接受一个(可选的)选项数组,您可以在其中指定两个标志:'timeham'
和'touch'
。如果Touch
设置为false
,那么无论您在模型上指定了任何$Touch
属性,Eloquent都不会触及相关模型。这都是Eloquent的保存()
方法的内置行为。
问题在于,Eloquent的create()
方法不接受任何传递到save()
的选项。通过扩展Eloquent(使用BaseModel
)以接受$options
数组作为第二个属性,并将其传递给save()
,您现在可以在所有扩展BaseModel
的模型上调用create()
时使用这两个选项。
请注意,$options
数组是可选的,因此这样做不会中断代码中对create()
的任何其他调用。
在代码源中,创建相关模型的新实例时,需要将$touch
设置为false:
Asset::create(array(),array(),false);
或使用:
$asset = new Asset;
// ...
$asset->setTouchedRelations([]);
$asset->save();
您可以使用touch
方法手动完成:
$product = Product::find($validId);
$product->assets()->attach($anotherValidId);
$product->touch();
但是如果你不想每次都手动完成,你可以这样在你的Products
模型中简化这个创建方法:
public function attachAsset($id)
{
$this->assets()->attach($id);
$this->touch();
}
现在您可以这样使用它:
Product::find($validId)->attachAsset($anotherValidId);
你当然可以为分离动作做同样的事情。
我注意到你有一个关系属于多个
,而另一个有很多
——两者都应该是属于多个
,因为这是多对多关系
编辑
如果您想在许多模型中使用它,您可以创建trait或创建另一个基类,该基类使用以下方法扩展了Eloquent:
public function attach($id, $relationship = null)
{
$relationship = $relationship ?: $this->relationship;
$this->{$relationship}()->attach($id);
$this->touch();
}
现在,如果您需要这个功能,您只需要从另一个基类(或使用特性)扩展,现在您可以在产品类中添加一个额外的属性:
private $relationship = 'assets';
现在您可以使用:
Product::find($validId)->attach($anotherValidId);
或
Product::find($validId)->attach($anotherValidId, 'assets');
如果需要通过更新附加数据updated_at
字段。当然,你需要重复分离。
我有一个表事务与复合主键id,Nom,日期和一个表Cour与Nom作为主键和一个事务有关一个Cour。 我怎样才能得到一个有口才关系的特定交易的课程?
问题内容: 我正在使用Eloquent进行数据库处理,当我使用更新方法更新记录时,时间戳被更改了,如何防止这种情况发生? 时间戳工作正常 问题答案: 如果您的模型中没有任何自定义设置。您可以像这样更新记录: 仅应使用此代码更新时间戳(而不是)。如果还进行了更新,则意味着您可能具有一些自定义模型设置,或者: 您可能具有数据库触发器,这些触发器在记录更新时会发生变化 您可能已经注册了一些事件,这些事件
我有以下三个表格: 所以基本上这种关系就像: 用户有许多项目 项目属性到客户端 我的问题是: 如何使用eloquent获得用户的所有客户端? 似乎我不能用户hasManyPass方法,因为在客户端表中没有project_id。 因此,我希望达到的目标是:
我在我的Laravel项目中与雄辩的关系作斗争。 我的数据库中有一个“用户”表和一个“用户行”表。“用户行”表中有一个“用户id”字段,该字段与“用户”中的“id”字段相对应,属于典型的主-明细关系。 用户模型与用户线模型有很多关系。UserLine模型与用户模型具有belongsTo关系。 在我的应用程序中,我有一个包含多个用户行的用户表单。在表单提交期间,可以添加、更改或删除这些用户行。到目前
我有这个模型文件:- 这是我的查询代码:- 我正在尝试附加getFacilityAttribute以包含在结果数组中。 我试图使用受保护的$append模型数组,但得到错误:- 调用未定义的方法照亮\数据库\雄辩\关系\属于::fac性()
我目前正在学习Laravel和Elotent,并且已经建立了一些初始迁移。我的一个表只需要一个创建时间,因为一旦在其中插入一行,它将永远不会被更新: 我理解,Eloquent在默认情况下希望出现在上创建的上更新的