我在 Controller 上的删除方法是这样的:
<?php
public function deleteMessage($id, $seller_id, $buyer_id)
{
//if the seller delete
if($seller_id == auth()->user->id)
//const DELETED_AT = 'deleted_by_seller';
//if the buyer delete
else($buyer_id == auth()->user->id)
//const DELETED_AT = 'deleted_by_buyer';
$result = Message::destroy($id);
return $result;
}
我的模型是这样的:
<?php
namespace App\Models;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
use Jenssegers\Mongodb\Eloquent\HybridRelations;
use Jenssegers\Mongodb\Eloquent\SoftDeletes;
class MessageThread extends Eloquent
{
use HybridRelations;
use SoftDeletes;
// const DELETED_AT = 'deleted_by_seller';
// const DELETED_AT = 'deleted_by_buyer';
protected $connection = 'mongodb';
protected $dates = ['deleted_by_seller', 'deleted_by_buyer'];
protected $fillable = ['subject', 'information', 'created_at', 'update_at'];
}
我想喜欢这个:
如果卖家删除消息则:const DELETED_AT = 'deleted_by_seller';
如果买家删除消息则:const DELETED_AT = 'deleted_by_buyer';
我该怎么做?
最佳答案
更新:
the original article refers my personal blog
在laravel中,我们通过扩展Illuminate\Database\Eloquent\Model来定义我们自己的模型。要软删除模型实例,我们应该在模型中使用 Illuminate\Database\Eloquent\SoftDeletes 特性。 runSoftDelete()是SoftDeletes trait中的关键函数,构建一个sql查询,获取用于标记记录是否被删除的列,然后更新该列带有当前时间戳。
protected function runSoftDelete()
{
$query = $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey());
$this->{$this->getDeletedAtColumn()} = $time = $this->freshTimestamp();
$query->update([$this->getDeletedAtColumn() => $this->fromDateTime($time)]);
}
当我们在模型上调用 delete() 函数时会发生什么?
由于我们自己的模型扩展了Illuminate\Database\Eloquent\Model,所以我们看一眼。这是 delete() 函数:
public function delete()
{
if (is_null($this->getKeyName())) {
throw new Exception('No primary key defined on model.');
}
if ($this->exists) {
if ($this->fireModelEvent('deleting') === false) {
return false;
}
// Here, we'll touch the owning models, verifying these timestamps get updated
// for the models. This will allow any caching to get broken on the parents
// by the timestamp. Then we will go ahead and delete the model instance.
$this->touchOwners();
$this->performDeleteOnModel();
$this->exists = false;
// Once the model has been deleted, we will fire off the deleted event so that
// the developers may hook into post-delete operations. We will then return
// a boolean true as the delete is presumably successful on the database.
$this->fireModelEvent('deleted', false);
return true;
}
}
代码清晰。它确保模型有一个 primaryKey 并且实例首先存在于数据库中。然后调用performDeleteOnModel()函数执行删除操作。一定要注意!
这里我们应该知道:
An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in turn override inherited methods.
因此,当调用 performDeleteOnModel() 时执行的确切函数是 SoftDeletes 特征中的同名函数,而不是 Model 中的函数类(class)。现在我们回到特征:
protected function performDeleteOnModel()
{
if ($this->forceDeleting) {
return $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey())->forceDelete();
}
return $this->runSoftDelete();
}
好吧,它会调用我们在开头讨论过的 runSoftDelete()。这就是软检测的过程。
提问者希望在删除时使用不同的DELETED_AT 列。通过仅覆盖 getDeletedAtColumn() 来保持软删除机制的良好运行还有很多不足之处。为什么被删除的模型被软删除了,结果还在结果中?
当 Model 类被构造时,它将通过调用它们的 boot[TraitName] 方法来启动特征。因此这里是 bootSoftDelete() 方法。
protected static function bootTraits()
{
foreach (class_uses_recursive(get_called_class()) as $trait) {
if (method_exists(get_called_class(), $method = 'boot'.class_basename($trait))) {
forward_static_call([get_called_class(), $method]);
}
}
}
现在让我们再次关注 SoftDeletes 特性。
public static function bootSoftDeletes()
{
static::addGlobalScope(new SoftDeletingScope);
}
这里的 trait 通过调用 static::addGlobalScope() 注册了一个具有 apply() 方法的 SoftDeletingScope 类。位于 Model 类中的方法将其存储到 $globalScopes 数组中。
public static function addGlobalScope(ScopeInterface $scope)
{
static::$globalScopes[get_called_class()][get_class($scope)] = $scope;
}
当一个查询建立在一个模型上时,applyGlobalScopes()方法会被自动调用,一个一个地访问$globalScopes数组中的实例并调用它们的 apply() 方法。
public function applyGlobalScopes($builder)
{
foreach ($this->getGlobalScopes() as $scope) {
$scope->apply($builder, $this);
}
return $builder;
}
我们现在将揭开问题的面纱。在 SoftDeletingScope 类中:
public function apply(Builder $builder, Model $model)
{
$builder->whereNull($model->getQualifiedDeletedAtColumn());
$this->extend($builder);
}
它将在每个查询上添加一个约束,以选择那些 DELETED_AT 列为空的记录。这就是 SoftDeletes 的 secret 。
首先,我需要重申,我不推荐使用动态 DELETED_AT 列的这种行为。
为了解决提问者的动态DELETED_AT列的问题,你需要用这样的apply()函数实现你自己的SoftDeletingScope类:
public function apply(Builder $builder, Model $model)
{
$builder->where(function ($query){
$query->where('DELETED_AT_COLUMN_1',null)->orWhere('DELETED_AT_COLUMN_2',null);
});
$this->extend($builder);
}
然后用它覆盖 bootSoftDeletes()
public static function bootSoftDeletes()
{
static::addGlobalScope(new YourOwnSoftDeletingScope);
}
原答案:
您不能在运行时更改const 变量的值。所以你需要手动分配CREATED_AT的值。
关于php - 如何创造条件上的 Eloquent 模式? (拉拉维尔 5.3),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42756671/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/