Laravel правильно ли поставить бизнес логи c в модель? - PullRequest
0 голосов
/ 04 апреля 2020

Я новичок в Laravel, и я не совсем понимаю, где разместить свои бизнес-логи c. На этом этапе я поместил бизнес-логику c в модель или службу (в зависимости от размера), чтобы мои контроллеры были максимально тонкими. Правильный ли мой подход? Я видел несколько примеров моделей, в которых были только отношения, но в данном случае, где хранить бизнес-логи c?

Вот примеры моей модели и сервиса Модель

class Test extends Model
{
    protected $fillable = ['name','description','category_id','difficulty','max_time','questions','max_points'];

   public function questions() // questions with answers related to chosen test
   {
       return $this->hasMany(Question::class)->inRandomOrder();
   }

    public function testCategories() // full info about every available category
    {
        return $this->with('category')
            ->select('category_id',
                DB::raw('min(difficulty) as minDifficulty'),
                DB::raw('max(difficulty) as maxDifficulty'),
                DB::raw('count(id) as total'))
            ->groupBy('category_id')
            ->get();
    }
    public function category()  // info about chosen tests category
    {
        return $this->belongsTo(Category::class,'category_id','id');
    }

    public function categoryTests($id,$testName = null)  // list of tests in chosen category
    {
        if(is_null($testName)) {
            return $this->with('category')
                ->where('category_id', $id)
                ->get();
        } else {
            return $this->with('category')
                ->where('name','like','%' . $testName . '%')
                ->get()
                ->sortBy('category_id');
        }
    }

    public function getTestData($id)  // get questions with answers + category
    {
        return $this->with(['questions.answers','category'])->where('id',$id)->get();
    }

    public function users()   // pivot table
    {
        $this->belongsToMany(User::class,'user_test');
    }



// Admin Section

    public function getAdminTestData($data)
    {
        return $this->with(['questionsCount','category'])
            ->where('id',($id ?? '!='),($id ?? 'null'))
            ->orderBy($data['orderBy'] ?? 'id',$data['param'] ?? 'asc')
            ->paginate(15);
    }


    public function questionsCount()
    {
        return $this->hasMany(Question::class)
            ->select('id','test_id',DB::raw('count(test_id) as total'))
            ->groupBy('test_id');

    }

    public function saveTest($data)
    {
       return $this->create([
            'name' => $data['testName'],
            'description' => $data['testDescription'],
            'category_id'=> $data['testCategory'],
            'difficulty' => $data['testDifficulty'],
            'max_time' => $data['maxTime'],
            'questions' => $data['questionsCount'],
            'max_points' => $data['max_points']
        ]);
    }

    public function getTestInfo($id)
    {
       return $this->with('getQuestionsInfo')->where('id',$id)->first();
    }

    public function updateTest($id,$data)
    {
        $this->find($id)->update([
            'name' => $data['name'],
            'category_id' => $data['category_id'],
            'description' => $data['description'],
            'max_time' => $data['max_time'],
            'difficulty' => $data['difficulty'],
        ]);
    }

    public function getQuestionsInfo()
    {
        return $this->hasMany(Question::class)->with(['answersCount']);
    }
}

Сервис

  public function handleTestCreate(Request $request) : void
    {
        $data =  $request->json()->all();
        $id = $this->model->saveTest($data)->id;
        foreach ($data['questions'] as $question) {
            $questionId = Question::create([
                'question_body' => $question['name'],
                'test_id' => $id,
                'points' => $question['points']
            ])->id;
            foreach ($question['answers'] as $answer) {
                Answer::create([
                    'answer_body' => $answer['name'],
                    'question_id' => $questionId,
                    'is_correct' => $answer['correct']
                ]);
            }
        }
    }

1 Ответ

0 голосов
/ 04 апреля 2020

Ваш подход совершенно противоположен тому, что рекомендуется. Контроллеры должны обрабатывать взаимодействие между вашим представлением и моделью. Модель должна содержать только детали, относящиеся к модели, такие как отношения, и то же самое относится к представлениям.

Введение в MVC framework: https://www.tutorialspoint.com/mvc_framework/mvc_framework_introduction.htm

Лично У меня было бы 3 контроллера для вопросов, категорий и администраторов, а также для модели, например, так:

Test. php

class Test extends Model
{
    protected $fillable = ['name','description','category_id','difficulty','max_time','questions','max_points'];

    public function category()  // info about chosen tests category
    {
        return $this->belongsTo(Category::class,'category_id','id');
    }

    public function users()   // pivot table
    {
        $this->belongsToMany(User::class,'user_test');
    }

    public function getQuestionsInfo()
    {
        return $this->hasMany(Question::class)->with(['answersCount']);
    }
}

QuestionController . php

use App\Test; // Import Model in Controller

namespace App\Http\Controllers;

class QuestionsController extends Controller
{
    public function questions() // questions with answers related to chosen test
    {
        return $this->hasMany(Question::class)->inRandomOrder();
    }

    public function getTestData($id)  // get questions with answers + category
    {
        return Test::with(['questions.answers','category'])->where('id',$id)->get();
    }
}

КатегорииКонтроллера. php

<?php

namespace App\Http\Controllers;

class CategoriesController extends Controller
{
    public function testCategories() // full info about every available category    {
        return $this->with('category')
            ->select('category_id',
                DB::raw('min(difficulty) as minDifficulty'),
                DB::raw('max(difficulty) as maxDifficulty'),
                DB::raw('count(id) as total'))
            ->groupBy('category_id')
            ->get();
    }

    public function categoryTests($id,$testName = null)  // list of tests in chosen category
    {
        if(is_null($testName)) {
            return $this->with('category')
                ->where('category_id', $id)
                ->get();
        } else {
            return $this->with('category')
                ->where('name','like','%' . $testName . '%')
                ->get()
                ->sortBy('category_id');
        }
    }

}

Admin Controller

<?php

use App\Test; // Import Model in Controller

namespace App\Http\Controllers;

class AdminController extends Controller
{
    public function getAdminTestData($data)
    {
        return Test::with(['questionsCount','category'])
            ->where('id',($id ?? '!='),($id ?? 'null'))
            ->orderBy($data['orderBy'] ?? 'id',$data['param'] ?? 'asc')
            ->paginate(15);
    }


    public function questionsCount()
    {
        return Test::hasMany(Question::class)
            ->select('id','test_id',DB::raw('count(test_id) as total'))
            ->groupBy('test_id');
    }

    public function saveTest($data)
    {
       return Test::create([
            'name' => $data['testName'],
            'description' => $data['testDescription'],
            'category_id'=> $data['testCategory'],
            'difficulty' => $data['testDifficulty'],
            'max_time' => $data['maxTime'],
            'questions' => $data['questionsCount'],
            'max_points' => $data['max_points']
        ]);
    }

    public function getTestInfo($id)
    {
       return Test::with('getQuestionsInfo')->where('id',$id)->first();
    }

    public function updateTest($id,$data)
    {
        Test::find($id)->update([
            'name' => $data['name'],
            'category_id' => $data['category_id'],
            'description' => $data['description'],
            'max_time' => $data['max_time'],
            'difficulty' => $data['difficulty'],
        ]);
    }
}

Код не гарантирован, так как может быть синтаксис или логическая ошибка, но структура - это то, что я пытаюсь донести.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...