Problem z zapisaniem do bazy Laravel

0

Siema, mam problem z zapisaniem do bazy. Gdy wykonuje od razu save do bazy w kontrolerze wszystko działa ale jak chce to zrobić z wykorzystaniem repository pattern to wyskakuje mi błąd Illuminate\Database\Eloquent\Model::save(): Argument #1 ($options) must be of type array, App\Models\Drink given. Co ciekawe $drink->save() normalnie przyjmuje obiekt.
screenshot-20210827182756.png

public function store(Request $request)
    {
        $drink = new Drink($request->all());

        $drink->author = Auth::id();
        dd($drink);
        $drink->save();

        //$this->drinkRepository->add($drink);

        return redirect()
            ->route('drinks')
            ->with('success', 'Drink created');
    }
interface DrinkRepositoryInterface
{
    public function get(int $id);
    public function list();
    public function add($drink);
}
class DrinkRepository implements DrinkRepositoryInterface
{
    private Drink $drinkModel;

    public function __construct(Drink $drinkModel)
    {
        $this->drinkModel = $drinkModel;
    }

    public function get(int $id)
    {
        return $this->drinkModel->find($id);
    }

    public function list()
    {
        return $this->drinkModel->get();
    }

    public function add($drink)
    {
        $this->drinkModel->save($drink);
    }
}
1

IMHO trochę przekombinowałeś - jeśli chcesz zrealizować repository pattern w Laraverze, najłatwiej oraz najczytelniej będzie np. tak:

class DrinkRepository implements DrinkRepositoryInterface
{
    public function get(int $id)
    {
        return Drink::find($id);
    }

    public function list()
    {
        return Drink::all();
    }

    public function add($drink)
    {
        $drink->save();
    }
}

Choć $this->drinkModel zdecydowanie wygląda bardziej hax0rsko, to niestety nie przynosi tu żadnej wartości :-)

(na marginesie - imo dużo sensowniej byłoby trzymać się jednej konwencji nazewniczej: skoro Laravel ma Model::find() oraz Model::all(), to najlepiej, aby Twoje repozytorium również miało tak nazwane metody.)

0

@Patryk27: Ok, jak sprawdzałem w internecie to dużo osób właśnie robiło z tym modelem. Co prawda zastosowanie tutaj repository pattern i tak jest overengineering przy tak małej aplikacji (a przynajmniej ja tak myślę :D) ale chciałem sobie sprawdzić jak to działa. Dzięki za pomoc, jeszcze co do nazw metod to fakt all() albo index() często widziałem ale żeby zamiast get() zrobić find() to już chyba nigdy.

1
Patryk27 napisał(a):

(na marginesie - imo dużo sensowniej byłoby trzymać się jednej konwencji nazewniczej: skoro Laravel ma Model::find() oraz Model::all(), to najlepiej, aby Twoje repozytorium również miało tak nazwane metody.)

Raloseq napisał(a):

jeszcze co do nazw metod to fakt all() albo index() często widziałem ale żeby zamiast get() zrobić find() to już chyba nigdy.

Wszystko co @Patryk27 napisał jest prawdą, zgadzam się w 100%.

Dodam tylko swoja dwa grosze, że z punktu widzenia zasady Dependency Inversion, to nie ma żadnego parcia na to żeby nazwy funkcji z modeli były spójne z nazwami w repozytorium. Celem repozytorium przecież od początku jest odseparowanie warstwy persystencji od domeny biznesowej, więc jakiekolwiek połączenia (nawet w nazwach funkcji) są nieporządane, lub wręcz odradzane.

Więc ja powiedziałbym że nie musisz zmieniać tych nazw, i get()/find() są okej w repozytorium.

Ale to zależy od Ciebie, i od tego czy chciałbyś stosować Dependency Inversion.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0