当前位置: 首页 > 知识库问答 >
问题:

更新附加/分离雄辩关系的时间戳

劳研
2023-03-14

我使用的是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 );

我哪里做错了?


共有3个答案

端木兴国
2023-03-14

创建扩展雄辩的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()的任何其他调用。

谷梁星雨
2023-03-14

在代码源中,创建相关模型的新实例时,需要将$touch设置为false:

Asset::create(array(),array(),false);

或使用:

$asset = new Asset;
// ... 
$asset->setTouchedRelations([]);
$asset->save();
叶鹭洋
2023-03-14

您可以使用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在默认情况下希望出现在上创建的上更新的