在Eloquent模型中,更新事件不启动


Updating event is not fire in Eloquent model

我创建了一个函数,用于更新有关EMI的贷款金额。在此函数中,贷款金额在EMI的创建和删除期间成功更新,但在EMI的更新时不成功。

EMI模型

    <?php namespace App;
       use Illuminate'Database'Eloquent'Model;
      class Emi extends Model {
    //
    protected  $table = 'emi';
    protected $fillable = ['loan_id', 'amount', 'description', 'date'];

    public function loan()
    {
        return $this->belongsTo('App'Loan');
    }
    public static function boot()
    {
        parent::boot();
        static::deleted(function($emi){
            $loan='App'Loan::find($emi->loan_id);
            $loan->paid -= $emi->amount;
            $loan->balance += $emi->amount;
            $loan->save();
        });
        static::saved(function($emi){
            $loan='App'Loan::find($emi->loan_id);
            $loan->paid += $emi->amount;
            $loan->balance -= $emi->amount;
            $loan->save();
        });
        static::updating(function($emi){
            $loan='App'Loan::find($emi->loan_id);
            $loan->paid -= $emi->amount;
            $loan->balance += $emi->amount;
            return $loan->save();
        });

    }
  }

Emi控制器

      <?php
       namespace App'Http'Controllers'Auth;
       use Illuminate'Http'Request as Request;
        use App'Http'Requests;
       use App'Http'Controllers'Controller;
      use Validator;
      use Response;
     use App'Account;
     use App'Loan;
     use App'Emi;
     class EmiController extends Controller
     { 
          /**
 * New data validation
 * @param array $data
 * @return 'Illuminate'Validation'Validator
 */
protected function validator(array $data)
{
    return Validator::make($data,[
        'loan_id'     =>'required|numeric',
        'amount'      =>'required|numeric|max:999999999999999999',
        'description' =>'required|alpha_text|max:250',
        'date'        =>'required|date',
    ]);
}
/**
 * Display a listing of the Emi resource.
 * If loan id is not given, then returns all Emi resource.
 * @param Request $request
 * @return 'Illuminate'Database'Eloquent'Collection|static[]
 */
public function index(Request $request)
{
    $loan_id = $request->get('loan_id');
    //All Emi recipets for loan
    if($loan_id !==NULL)
        return Loan::find($loan_id)->emi;
    else
        return Emi::with('loan')->get();
}
/**
 * Show the form for creating a new resource.
 *
 * @return Response
 */
public function create()
{
    //
}
/**
 * Store a newly created resource in storage.
 * @param Request $request
 * @return Response
 */
public function store(Request $request)
{
    $validator = $this->validator($request->all());
    if($validator->fails()){
        return Response::json( $validator->errors()
            ,400);
    }
    $emi = new Emi($request->all());
    //TODO Loan balance update
    if($emi->save()){
        return $emi;
    }
    return Response::json( ['error' => 'Server is down']
        ,500);
}
/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return Response
 */
public function show($id)
{
    //
    return Emi::find($id);
}
/**
 * Show the form for editing the specified resource.
 *
 * @param  int  $id
 * @return Response
 */
public function edit($id)
{
    //
}
/**
 * Update the specified resource in storage.
 * @param $id
 * @param Request $request
 * @return 'Illuminate'Http'JsonResponse
 */
public function update($id,Request $request)
{
    $validator = $this->validator($request->all());
    if($validator->fails()){
        return Response::json($validator->errors()
            ,400);
    }
    //TODO Update loan  balance
    $emi = Emi::find($id);
    //$emi->fill($request->all());
    if($emi->update($request->all())){
        return $emi;
    }
    return Response::json( ['error' => 'Server is down']
        ,500);
}

/**
 * Remove the specified resource from storage.
 *
 * @param  int  $id
 * @return Response
 */
public function destroy($id)
{
    //TODO delete emi balance change in loan
    if(Emi::destroy($id))
        return Response::json(array('msg'=>'Emi deleted'));
    else
        return Response::json(array('error'=>'Records not found'),400);
   }
 }

我在使用Model的事件系统时遇到了一些问题。有时它就是不工作,而且它的缺点是你不能把所有依赖的DB操作放在一个事务中。

虽然有点黑客,我认为插入/更新/删除相关模型最可靠的方法(如果你想确保DB关系完整性)是通过扩展save()和delete()方法,像这样:

class Model extends Eloquent {
    $hasCustomInsert = false;
    $hasCustomUpdate = false;
    $hasCustomDelete = false;
    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        foreach(get_class_methods($this) as $method) {
            if (in_array($method,['preInsert','postInsert'])) $this->hasCustomInsert = true;
            if (in_array($method,['preEdit','postEdit'])) $this->hasCustomUpdate = true;
            if (in_array($method,['preDelete','postDelete'])) $this->hasCustomDelete = true;
        }
    }
    public function save(array $options = [])
    {
        //Custom Insert
        if (!$this->exists && $this->hasCustomInsert) {
            return DB::transaction(function() use($options) {
                $this->preInsert();
                $saved = parent::save($options);
                $this->postInsert();
                return $saved;
            });
        }
        //Custom Update
        if ($this->exists && $this->hasCustomUpdate) {
            return DB::transaction(function() use($options) {
                $this->preEdit();
                $saved = parent::save($options);
                $this->postEdit();
                return $saved;
            });
        }
        return parent::save($options);
    }
    public function delete()
    {
        //Custom Delete
        if ($this->exists && $this->hasCustomDelete) {
            return DB::transaction(function() {
                $this->preDelete();
                $deleted = parent::delete();
                $this->postDelete();
                return $deleted;
            });
        }
        return parent::delete();
    }
}

在扩展Eloquent的自定义基Model类上使用这个。所有的模型都应该从基类扩展,而不是直接扩展Eloquent。

然后,您可以在您的子模型的preInsert(), postInsert(), preEdit(), postEdit(), preDelete()和postDelete()方法中添加您想要的任何内容。如果子模型没有实现这些方法,save()和delete()会像往常一样调用Eloquent的方法。