swoft-cloud / swoft

🚀 PHP Microservice Full Coroutine Framework
https://swoft.org
Apache License 2.0
5.58k stars 788 forks source link

Feature request: Model soft delete and Pagination. #1183

Closed MattCraftsCode closed 4 years ago

MattCraftsCode commented 4 years ago
Q A
Bug report? no
Feature request? yes
Swoft version 2.0.7
Swoole version 4.4.8
PHP version 7.3.12

Expected behavior 用惯了 Laravel,觉得 "软删除" 和 "分页组件" 很好用,希望 Swoft 也可以有。 Soft delete and Pagination are convenient components in Laravel

Details

  1. Soft delete

软删除让代码更简洁: If using "soft delete" in laravel, code is very elegant: (有软删除)

User::where('name', 'some')
  ->leftJoin('orders', 'orders.user_id', 'users.id')->get();

If no soft delete, we have to go handle "deleted_at" for every related tables: (无软删除)

User::whereNull('users.deleted_at')
  ->leftJoin('orders', 'orders.user_id', 'users.id')
  ->whereNull('orders.deleted_at')
  ->get();

其他原因:

Other reasons:

  1. Pagination

Without pagination:

I need a traits


/**
 * Trait PaginateHelper
 * @package App\Helper
 */
trait PaginateHelper
{

    /**
     * @param Builder $builder
     * @return Builder
     * @throws ApiException
     */
    public function paginate(Builder $builder): Builder
    {
        if (!$builder) {
            throw new ApiException('Builder is null');
        }

        $page = intval(req()->input('page', 1));
        $size = intval(req()->input('size', 10));

        if ($page <= 0) {
            $page = 1;
        }

        if ($size <= 0) {
            $size = 10;
        }

        return $builder->skip(($page - 1) * $size)->limit($size);
    }

    /**
     * @param array $data
     * @param int $total
     * @return array
     */
    public function paginateResponseWrapper(array $data, int $total): array
    {
        $page = intval(req()->input('page', 1));
        $size = intval(req()->input('size', 10));

        return [
            'data' => $data,
            'current_page' => $page,
            'per_page' => $size,
            'total' => $total,
        ];
    }
}

and using in controller:

class Controller {
  use PaginateHelper;

  public function list(){
       $builder = User::whereNull('deleted_at');
        $total = $builder->count();

        // handle paginate
        $builder = $this->paginate($builder);

        $wrapper = $this->paginateResponseWrapper($this->collect($builder->get(), UserTransformer::class), $total);
        return json_response($wrapper);
  }
}

With pagination:

class Controller {
  use PaginateHelper;

  public function list(){
       $builder = User::whereNull('deleted_at');
        return json_response($this->collect($builder->paginate(), UserTransformer::class));
  }
}
sakuraovq commented 4 years ago

forPage Support pagination image

paginate, paginateById method already support simple paginator.

sakuraovq commented 4 years ago

Database design null type, generally not allowed Soft delete is generally controlled by business design. This makes business more convenient

sakuraovq commented 4 years ago

thank you for your advice ~

MattCraftsCode commented 4 years ago

Thank you~