Can't get the laravel custom repository to work - laravel

I can't get my repository working, when i'm just trying the get the entire list of documents it returns nothing
Here's my DocumentRepository
<?php
namespace App\Repositories\Document;
interface DocumentRepository
{
public function getall();
public function getById($id);
public function create(array $attributes);
public function update ($id, array $attributes);
public function delete ($id);
}
Here's the functions
<?php
namespace App\Repositories\Document;
class EloquentDocument implements DocumentRepository
{
private $model;
public function __construct(Document $model)
{
$this->model = $model;
}
public function getall()
{
return $this->model->all();
}
public function getById($id)
{
return $this->findById($id);
}
public function create(array $attributes)
{
return $this->model->create($attributes);
}
public function delete($id)
{
$this->getById($id)->delete();
return true;
}
public function update($id array $attributes)
{
$document = $this->model->findOrFail($id);
$document->update($attribute);
return $document;
}
}
and here's the controller
<?php
namespace App\Http\Controllers;
use App\Repositories\Document;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class DocumentController extends Controller
{
/**
* #var DocumentRepository
*/
private $document;
/**
* TodoController constructor.
*/
public function __construct(DocumentController $document)
{
$this->document = $document;
}
public function getalldocuments()
{
return $this->document->getAll();
}
}
For your information there's two rows of data in my Documents table/model so i just want to get both of them by just simply returning but in my case it simply returns nothing.
Here's the route
Route::get('/documents', 'DocumentController#getalldocuments');
here's the registration part insite AppServiceProviders.php
public function register()
{
$this->app->singleton(DocumentRepository::class, EloquentDocument::class);
}

You are type-hinting DocumentController instead of your actual repository.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Repositories\Document\DocumentRepository;
class DocumentController extends Controller
{
/**
* #var DocumentRepository
*/
private $document;
public function __construct(DocumentRepository $document)
{
$this->document = $document;
}
public function getalldocuments()
{
return $this->document->getAll();
}
}
Now, assuming you have properly binded the interface to resolve to your document repository implemented, this should work.
For more information on how to bind interfaces to implementation, read this: https://laravel.com/docs/5.7/container#binding-interfaces-to-implementations
Edit: You have some syntax issues in your repository's interface. You are missing function:
<?php
namespace App\Repositories\Document;
interface DocumentRepository
{
public function getall();
public function getById($id);
public function create(array $attributes);
public function update($id, array $attributes);
public function delete($id);
}
Edit 2: Your binding is correct. However, I noticed that you are not binding your App\Document model to the implementation correctly.
<?php
namespace App\Repositories\Document;
use App\Document;
class EloquentDocument implements DocumentRepository
{
private $model;
public function __construct(Document $model)
{
$this->model = $model;
}
//
//
//
}
You need to add the correct use statement at the top. Assuming your document model resides in App\Document this should work.

Related

Testing Custom Route Model Binding

I'm trying to test a custom class that implements \Illuminate\Contracts\Routing\UrlRoutable and can't get the resolveRouteBinding method invoked.
<?php
namespace Tests\Unit;
use Illuminate\Support\Facades\Route;
use Tests\TestCase;
class BindingExampleClassTest extends TestCase
{
function test_invoke_resolve_route_binding_method()
{
Route::get('/invoke-route-binding/{binding}', function (BindingExampleClass $binding) {
dd($binding);
});
$this->get('/invoke-route-binding/1');
}
}
class BindingExampleClass implements \Illuminate\Contracts\Routing\UrlRoutable
{
public $id;
public function resolveRouteBinding($value, $field = null)
{
$this->id = $value;
}
public function getRouteKey()
{
// TODO: Implement getRouteKey() method.
}
public function getRouteKeyName()
{
// TODO: Implement getRouteKeyName() method.
}
public function resolveChildRouteBinding($childType, $value, $field)
{
// TODO: Implement resolveChildRouteBinding() method.
}
}
The dd response is BindingExampleClass with id still null.
Registering route inside a test function will not include any middleware. When working with route model binding in Laravel, \Illuminate\Routing\Middleware\SubstituteBindings::class middleware must be defined in the router instance.
Route::get('/invoke-route-binding/{binding}', function (BindingExampleClass $binding) {
dd($binding);
})->middleware(\Illuminate\Routing\Middleware\SubstituteBindings::class);

Target class [App\Repositories\User\UserRepository] does not exist

I'm using laravel and try to integrate the repository in laravel.
follow this link https://www.itsolutionstuff.com/post/laravel-5-repository-pattern-tutorial-from-scratchexample.html.
but getting the below issue. don't know what's wrong with code. try to find a solution but not getting any particular solution.
UserInterface
namespace App\Repositories\User;
interface UserInterface {
public function getAll();
public function find($id);
public function delete($id);
}
UserRepoServiceProvide
use Illuminate\Support\ServiceProvider;
class UserRepoServiceProvide extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind('App\Repositories\User\UserInterface', 'App\Repositories\User\UserRepository');
}
UserRepository
use App\Repositories\User\UserInterface as UserInterface;
use App\User;
class UserRepository implements UserInterface
{
public $user;
function __construct(User $user) {
$this->user = $user;
}
public function getAll()
{
return $this->user->getAll();
}
public function find($id)
{
return $this->user->findUser($id);
}
public function delete($id)
{
return $this->user->deleteUser($id);
}
}
User Model
public function getAll()
{
return static::all();
}
public function findUser($id)
{
return static::find($id);
}
public function deleteUser($id)
{
return static::find($id)->delete();
}
UserController
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Repositories\User\UserInterface as UserInterface;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function __construct(UserInterface $user)
{
$this->user = $user;
}
public function index()
{
$users = $this->user->getAll();
return view('users.index',['users']);
}
}
composer.json
"autoload": {
"psr-4": {
"App\\": "app/",
"App\\Repositories\\": "app/Repositories/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
but still getting this issue
Please Help.
folder path
In your UserController :
remove
use App\Repositories\User\UserInterface as UserInterface;
and add
use App\Repositories\User\UserRepository as UserInterface;

Cannot declare class App\User, because the name is already in use Laravel

I want to add user address in address table and want to update the address_id in user table for that i'm using user model and address model, data is being saved in address table but when i use User model in Address Repository
use App\Models\User;
i get
Cannot declare class App\User, because the name is already in use
Here is my code :
<?php
namespace App\Repositories;
use App\Models\Addresses;
use App\Models\User;
use App\Contracts\AddressContract;
use Illuminate\Database\QueryException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Doctrine\Instantiator\Exception\InvalidArgumentException;
class AddressRepository extends BaseRepository implements AddressContract
{
/**
* AttributeRepository constructor.
* #param Attribute $model
*/
public function __construct(Addresses $model)
{
parent::__construct($model);
$this->model = $model;
}
public function addAddress(array $params)
{
try {
$Addresses = new Addresses($params);
$Addresses->save();
$addressId = $Addresses->id;
$userID=auth()->user()->id;
if($params['is_primary_address']==1)
{
User::where('id',$userID)->update(['address_id'=>$addressId]);
}
return $Addresses;
}
catch (QueryException $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
}
}
ProductController.php
<?php
namespace App\Http\Controllers\Site;
use App\Contracts\AttributeContract;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Contracts\ProductContract;
use App\Contracts\AddressContract;
use Cart;
use Validator;
class ProductController extends Controller
{
protected $productRepository;
protected $attributeRepository;
protected $addressRepository;
public function __construct(ProductContract $productRepository, AttributeContract $attributeRepository, AddressContract $addressRepository)
{
$this->productRepository = $productRepository;
$this->attributeRepository = $attributeRepository;
$this->addressRepository = $addressRepository;
}
public function addUserAddress(Request $request)
{
$customer_name=$request->customer_name;
$customer_address=$request->customer_address;
$country=$request->country;
$city=$request->city;
$zip_code=$request->zip_code;
$state=$request->state;
$address_type=$request->address_type;
$is_primary_address=$request->primary_address;
$userID=auth()->user()->id;
$data=array('name'=>$customer_name,'address'=>$customer_address,'country'=>$country,'state'=>$state,'city'=>$city,'address_type'=>$address_type,'user_id'=>$userID,'is_primary_address'=>$is_primary_address);
$userAddress = $this->addressRepository->addAddress($data);
return redirect()->back()->with('message', 'Address Added');
}
}

Laravel repository Class App\Repository\User does not exist

Hello I want to use my own repository class in my Laravel 5.8 project
I created my file Repository in the App File and in this file I added A class called ConversationRepository
This is my class:
<?php
namespace App\Repository;
class ConversationRepository{
private $user;
public function __construct(User $user){
$this->user=$user;
}
public function getConversation(int $userId){
return $this->user->newQuery()
->select('name','id')
->where('id','!=',$userId)
->get();
}
}
And then when I use it on my controller :
<?php
namespace App\Http\Controllers;
use App\User;
use Auth;
use Illuminate\Http\Request;
use App\Repository\ConversationRepository;
class ConversationsController extends Controller
{
private $r;
private $auth;
public function __construct(ConversationRepository $conversationRepository,AuthManager $auth){
$this->r = $conversationRepository;
$this->auth = $auth;
}
public function index(){
return view('conversation.index',[
'users'=>$this->r->getConversation($this->auth->user()->id)
]);
}
public function show(User $user){
return view('conversation.show',['users'=>$this->r->getConversation(
$this->auth->user()->id),
'user'=>$user
]);
}
public function store(User $user){
}
}
I get the error
Class App\Repository\User does not exist
Apparently, you forgot to add use App\User; in the class ConversationsController file.

Override Eloquent Relation Create Method

I want to override create method, but with relation, it didn't touch the create method.
There are Two Models:
class User extends Model
{
public function user_detail()
{
return $this->hasOne(UserDetail::class);
}
}
class UserDetail extends Model
{
public static function create(array $attributes = [])
{
//I was trying to do something like
/*
if(isset($attributes['last_name']) && isset($attributes['first_name']))
{
$attributes['full_name']=$attributes['first_name'].' '.$attributes['last_name'];
}
unset($attributes['first_name'],$attributes['last_name']);
*/
Log::debug('create:',$attributes);
$model = static::query()->create($attributes);
return $model;
}
}
When I use UserDetail::create($validated), and there is a log in laravel.log, so I know the code touched my custom create method.
But if I use
$user = User::create($validated);
$user->user_detail()->create($validated);
There is no log in laravel.log, which means laravel didn't touch the create method, then how I supposed to do to override create method under this circumstance?(I'm using laravel 5.7)
Thank you #Jonas Staudenmeir, after I read the documentation, here is my solution.
If the $attributes are not in protected $fillable array, then I do it in the __construct method.
class UserDetail extends Model
{
protected $fillable=['full_name','updated_ip','created_ip'];
public function __construct(array $attributes = [])
{
if (isset($attributes['first_name']) && isset($attributes['last_name'])) {
$attributes['full_name'] = $attributes['first_name'].' '.$attributes['last_name'];
}
parent::__construct($attributes);
}
}
Otherwise, I do it in Observer.
namespace App\Observers;
use App\Models\UserDetail;
class UserDetailObserver
{
public function creating(UserDetail $userDetail)
{
$userDetail->created_ip = request()->ip();
}
public function updating(UserDetail $userDetail)
{
$userDetail->updated_ip = request()->ip();
}
}
Register Observer in AppServiceProvider.
namespace App\Providers;
use App\Models\UserDetail;
use App\Observers\UserDetailObserver;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
UserDetail::observe(UserDetailObserver::class);
}
}
I choose Observer instead of Event&Listener is for easy maintenance.

Resources