Tomoe

573 经验值

真正的大神來了,跪之 Orz

換名字?我一直都是這個阿,你該不會以為我是 JellyBool ...

如果你是自己寫了一個類來處理文章相關的業務邏輯,裡面有個 delete 函數可以刪除文章和評論 ( 如你所說 ),在你絕對都是透過這個類來刪除文章的前提下,那當然是沒問題,但是可能會有些情況你刪除並不是透過你寫的 delete 函數,例如:


$post = Post::find(20);
$post->delete();

這時候的刪除就沒通過類裡面定義的函數,是直接呼叫 Modeldelete,自然不會連帶評論一起被刪除。

所以我上面用事件的用意是在更 底層 的地方,實現連帶刪除評論這件事,這樣你不管是什麼方法刪除,都會觸發上面的事件,這樣自然能保證刪除文章一定會連帶刪除評論。

可以用 Model Event 來處理:

class Post extends Model {
  // 略

  protected static function boot() {
      parent::boot();
        
      // 當文章被刪除時會觸發該事件
      static::deleting(function($post) {
          // 刪除關聯的評論
          $post->comments()->delete();
      });
  }
}

其實可以改變一下方式,改用 firstOrNew

$instance = SomeModel::firstOrNew($attributes); // 查找,找不到就建立一個模型實體 ( 尚未寫入 )

if( !$instance->exists ) { // 這裡就可以判斷是否為原來存在的,false 代表不存在是新建立的

   // do something

  $instance->save(); // 這裡才是真正寫入

}

你的報錯有點奇怪:

There are no commands defined in the "db:" namespace.

正常來講找不到 namespace 應該是這樣

There are no commands defined in the "db" namespace.

你卻多了一個冒號,感覺是打成了 db::seed

剛剛故意打錯的指令來試的結果。

大神別呀,小弟只是剛好用過~

static 關鍵字可以讓當前 function 記住該值,在之後執行時都會沿用之前的值

function increment() {
    static $num =  0; // 這裡只會在第一次被 call 時執行,所以只會做初始化值一次
    $num++; 
    echo $num;
}

increment(); // => 1
increment(); // => 2
increment(); // => 3
increment(); // => 4

放到 ModelFactory 來講的話,完整的 Code 應該是這樣:

$factory->define(App\User::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});

$password 在第一次執行時是 NULL 的 ( 只有宣告沒賦值 ),會跑 $password = bcrypt('secret')
那因為 $password 都會被記住,之後就都會直接去使用 $password 而不會再跑一次 bcrypt('secret')

有點花式的用法,不過在效能上會有所提升。

@tlerbao 主要目的都是為了解耦,如果業務邏輯並不複雜其實不用過度設計。

剛好最近有在 Laravel News 看見這個,其實 issue 有人問作者為何要用 job ,作者的理由是他只是試驗一下 Laravel 的特性

https://github.com/austintoddj/Canvas/issues/29

可以使用 dingo/api

可以很簡單實現你要的功能:

$api->version('v1', function ($api) {

});

$api->version('v2', function ($api) {

});