Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dhcmega's avatar

How should I treat the repository? As a Model?

Hi all I am working on a Laravel project using infyomlabs/laravel-generator", so I have all my Controllers and Models, along with many more files, automatically created/generated. Among all these files, I have the Repositories.

I see 2 ways of using it, and it's getting me confused.

One way is passing the id of the element I want to work with, as a param to the method (Like with a regular model):

    public function edit($id)
    {
        $organization = $this->organizationRepository->findWithoutFail($id);

        if (empty($organization)) {
            Flash::error('Organization not found');

            return redirect(route('organizations.index'));
        }

        return view('organizations.edit')->with('organization', $organization);
    }

But there is also a none instantiation way:

    public function destroy($id)
    {
        $product = $this->productRepository->findWithoutFail($id);

        if (empty($product)) {
            Flash::error('Product not found');

            return redirect(route('products.index'));
        }

        $this->productRepository->delete($id);

        Flash::success('Product deleted successfully.');

        return redirect(route('products.index'));
    }

Where I instead of using the $product variable, passing the $id variable to delete() method forces for a new database find().

When I try to use the Repository as a Model, and call a Method within the Repository, I get the error "Call to undefined method Illuminate\Database\Query\Builder::updateSpecials()". But the updateSpecials method exists in the ProductRepository class. Also, within the repository class, I cannot do $this->model->id and get the id of the record it should (?) have as id.

    /**
     * Update the specified Product in storage.
     *
     * @param  int              $id
     * @param UpdateProductRequest $request
     *
     * @return Response
     */
    public function update($id, UpdateProductRequest $request)
    {
        $product = $this->productRepository->with('specials')->find WithoutFail($id);
        $product->updateSpecials($request['special']);
    }

Maybe I just have to call a repository method like this:

$this->productRepository->updateSpecials($id, $request['special']);

That way it works, but inside ProductRepository I have to do $this->model::find($id); to find the record I want to update. Also a dd() of the response of the above code, gives me an empty/new product object.

Clearly, I don't understand how should I handle repositories. Can anyone please help on this? Thanks!

Edit: Added information:

This code:

        dd(get_class_methods($this->productRepository));

Will output this:

array:53 [▼
  0 => "model"
  1 => "updateSpecials"
  2 => "updateTurns"
  3 => "generateThumbnail"
  4 => "findWithoutFail"
  5 => "create"
  6 => "update"
  7 => "updateRelations"
  8 => "__construct"
  9 => "boot"
  10 => "resetModel"
  11 => "presenter"
  12 => "validator"
  13 => "setPresenter"
  14 => "makeModel"
  15 => "makePresenter"
  16 => "makeValidator"
  17 => "getFieldsSearchable"
  18 => "scopeQuery"
  19 => "lists"
  20 => "pluck"
  21 => "sync"
  22 => "syncWithoutDetaching"
  23 => "all"
  24 => "first"
  25 => "firstOrNew"
  26 => "firstOrCreate"
  27 => "paginate"
  28 => "simplePaginate"
  29 => "find"
  30 => "findByField"
  31 => "findWhere"
  32 => "findWhereIn"
  33 => "findWhereNotIn"
  34 => "updateOrCreate"
  35 => "delete"
  36 => "deleteWhere"
  37 => "has"
  38 => "with"
  39 => "withCount"
  40 => "whereHas"
  41 => "hidden"
  42 => "orderBy"
  43 => "visible"
  44 => "pushCriteria"
  45 => "popCriteria"
  46 => "getCriteria"
  47 => "getByCriteria"
  48 => "skipCriteria"
  49 => "resetCriteria"
  50 => "resetScope"
  51 => "skipPresenter"
  52 => "parserResult"
]

And, this code:

        $product = $this->productRepository->with('specials')->findWithoutFail($id);
        dd(get_class_methods($product));

Will output this:

array:191 [▼
  0 => "getTimeDropDown"
  1 => "getFormatedLocationExtraPriceAttribute"
  2 => "getLocationExtraPriceAttribute"
  3 => "setKidPriceAttribute"
  4 => "setAdultPriceAttribute"
  5 => "setDateFromAttribute"
  6 => "setDateToAttribute"
  7 => "getDateFromAttribute"
  8 => "getDateToAttribute"
  9 => "account"
  10 => "activityLocation"
  11 => "productType"
  12 => "user"
  13 => "activityTurns"
  14 => "bookings"
  15 => "coupons"
  16 => "pickupLocations"
  17 => "users"
  18 => "specials"
  19 => "__construct"
  20 => "clearBootedModels"
  21 => "fill"
  22 => "forceFill"
  23 => "newInstance"
  24 => "newFromBuilder"
  25 => "on"
  26 => "onWriteConnection"
  27 => "all"
  28 => "with"
  29 => "load"
  30 => "update"
  31 => "push"
  32 => "save"
  33 => "saveOrFail"
  34 => "destroy"
  35 => "delete"
  36 => "forceDelete"
  37 => "query"
  38 => "newQuery"
  39 => "newQueryWithoutScopes"
  40 => "newQueryWithoutScope"
  41 => "newEloquentBuilder"
  42 => "newCollection"
  43 => "newPivot"
  44 => "toArray"
  45 => "toJson"
  46 => "jsonSerialize"
  47 => "fresh"
  48 => "refresh"
  49 => "replicate"
  50 => "is"
  51 => "getConnection"
  52 => "getConnectionName"
  53 => "setConnection"
  54 => "resolveConnection"
  55 => "getConnectionResolver"
  56 => "setConnectionResolver"
  57 => "unsetConnectionResolver"
  58 => "getTable"
  59 => "setTable"
  60 => "getKeyName"
  61 => "setKeyName"
  62 => "getQualifiedKeyName"
  63 => "getKeyType"
  64 => "setKeyType"
  65 => "getIncrementing"
  66 => "setIncrementing"
  67 => "getKey"
  68 => "getQueueableId"
  69 => "getRouteKey"
  70 => "getRouteKeyName"
  71 => "getForeignKey"
  72 => "getPerPage"
  73 => "setPerPage"
  74 => "__get"
  75 => "__set"
  76 => "offsetExists"
  77 => "offsetGet"
  78 => "offsetSet"
  79 => "offsetUnset"
  80 => "__isset"
  81 => "__unset"
  82 => "__call"
  83 => "__callStatic"
  84 => "__toString"
  85 => "__wakeup"
  86 => "attributesToArray"
  87 => "relationsToArray"
  88 => "getAttribute"
  89 => "getAttributeValue"
  90 => "getRelationValue"
  91 => "hasGetMutator"
  92 => "setAttribute"
  93 => "hasSetMutator"
  94 => "fillJsonAttribute"
  95 => "fromJson"
  96 => "fromDateTime"
  97 => "getDates"
  98 => "setDateFormat"
  99 => "hasCast"
  100 => "getCasts"
  101 => "getAttributes"
  102 => "setRawAttributes"
  103 => "getOriginal"
  104 => "syncOriginal"
  105 => "syncOriginalAttribute"
  106 => "isDirty"
  107 => "isClean"
  108 => "getDirty"
  109 => "append"
  110 => "setAppends"
  111 => "getMutatedAttributes"
  112 => "cacheMutatedAttributes"
  113 => "observe"
  114 => "getObservableEvents"
  115 => "setObservableEvents"
  116 => "addObservableEvents"
  117 => "removeObservableEvents"
  118 => "saving"
  119 => "saved"
  120 => "updating"
  121 => "updated"
  122 => "creating"
  123 => "created"
  124 => "deleting"
  125 => "deleted"
  126 => "flushEventListeners"
  127 => "getEventDispatcher"
  128 => "setEventDispatcher"
  129 => "unsetEventDispatcher"
  130 => "addGlobalScope"
  131 => "hasGlobalScope"
  132 => "getGlobalScope"
  133 => "getGlobalScopes"
  134 => "hasOne"
  135 => "morphOne"
  136 => "belongsTo"
  137 => "morphTo"
  138 => "getActualClassNameForMorph"
  139 => "hasMany"
  140 => "hasManyThrough"
  141 => "morphMany"
  142 => "belongsToMany"
  143 => "morphToMany"
  144 => "morphedByMany"
  145 => "joiningTable"
  146 => "touches"
  147 => "touchOwners"
  148 => "getMorphClass"
  149 => "getRelations"
  150 => "getRelation"
  151 => "relationLoaded"
  152 => "setRelation"
  153 => "setRelations"
  154 => "getTouchedRelations"
  155 => "setTouchedRelations"
  156 => "touch"
  157 => "setCreatedAt"
  158 => "setUpdatedAt"
  159 => "freshTimestamp"
  160 => "freshTimestampString"
  161 => "usesTimestamps"
  162 => "getCreatedAtColumn"
  163 => "getUpdatedAtColumn"
  164 => "getHidden"
  165 => "setHidden"
  166 => "addHidden"
  167 => "getVisible"
  168 => "setVisible"
  169 => "addVisible"
  170 => "makeVisible"
  171 => "makeHidden"
  172 => "getFillable"
  173 => "fillable"
  174 => "getGuarded"
  175 => "guard"
  176 => "unguard"
  177 => "reguard"
  178 => "isUnguarded"
  179 => "unguarded"
  180 => "isFillable"
  181 => "isGuarded"
  182 => "totallyGuarded"
  183 => "bootSoftDeletes"
  184 => "restore"
  185 => "trashed"
  186 => "restoring"
  187 => "restored"
  188 => "isForceDeleting"
  189 => "getDeletedAtColumn"
  190 => "getQualifiedDeletedAtColumn"
]
0 likes
4 replies
dhcmega's avatar

Hi primordial, I will read it. Thanks. My question is, How should I think of the repository? I had the idea that it would be like calling a Model, but with the added value of using one more layer. What I see is that when I just call the Repo, I can only use its methods. But, when I instantiate it, I can only use the methods of the model that it's behind it. Thanks again.

primordial's avatar

The repository is a layer of abstraction between the controller and permanent storage. Ideally, you don't want your controllers talking direct to your models, only via the repository. Your tend to duplicate a lot of model methods inside your repository to help this happen and the repositories should return any model data as arrays.

dhcmega's avatar

Ok, I will read what you sent me and come back if I have more questions. Thanks for your help!

Please or to participate in this conversation.