Problem z zapisaniem do bazy Laravel

Problem z zapisaniem do bazy Laravel
Raloseq
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 291
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

Kopiuj
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');
    }
Kopiuj
interface DrinkRepositoryInterface
{
    public function get(int $id);
    public function list();
    public function add($drink);
}
Kopiuj
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);
    }
}
Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
1

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

Kopiuj
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.)

Raloseq
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 291
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.

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.