In web.php I have this route which opens a form:
$this->namespace('Users')->prefix('users')->group(function (){
$this->get('/create' , 'UserController#create');
});
And this route returns an array of countries. I use that array to fill a select box via ajax in the form.
Route::namespace('API')->prefix('api')->group(function () {
$this->get('/get-country-list', 'LocationsController#index');
});
Controller:
app\Http\Controllers\API\LocationsController
class LocationsController extends Controller
{
public function index()
{
return DB::table('countries')->pluck("name","id")->all();
}
...
app\Http\Controllers\Users\UserController
class UserController extends Controller
{
public function create()
{
return view('panel.users.home.create.show');
}
...
How can I call LocationsController#index in create() function?
what is the best method?
you can try return redirect(route('...')); instead of return view() in actions.
update
Because you just want to get Countries list instead of redirection. So do small tuning, separate the data manipulating function from the action function:
protected function getCountries() {
return DB::table('countries')->pluck("name","id")->all();
}
function index(Request $request) {
return $this->getCountries();
}
function create(Request $request) {
$countries = $this->getCountries();
return view('panel.users.home.create.show', compact('countries'));
}
I think you should try a different approach. What you seem to be trying to do is reuse this cumbersome query:
DB::table('countries')->pluck('name', 'id')->all();
That's good! However your index() function is a controller endpoint and which returns a response and isn't really suitable for being reused in other controller endpoints. When I am in a similar situation I usually do one of two things,
1. Extract the code to a protected method and use it in both controller endpoint methods
class UserController extends Controller
{
public function index()
{
return $this->countryNames();
}
public function create()
{
// $countryNames = $this->countryNames():
return view('panel.users.home.create.show');
}
public function countryNames()
{
return DB::table('countries')->pluck('name', 'id')->all();
}
}
2. Create a method on the model, in your case this would involve using the model instead of the DB facade.
class UserController extends Controller
{
public function index()
{
return Country::names();
}
public function create()
{
// $countryNames = Country::names();
return view('panel.users.home.create.show');
}
}
Related
I created a resourceful Laravel livewire component instead of going the controller route and was wondering if this practice is a clean approach? I've also eliminated the render method and have 3 methods that display a view. the problem with this I've noticed is that the wire:submit.prevent won't work.
for example routes
Route::resource('products', 'ProductComponent');
Component:
class ProductComponent extends Component
{
public function index()
{
return view('mypage');
}
public function create()
{
return view('create page');
}
public function store()
{
//
}
public function edit(Model $model)
{
return view('edit page');
}
public function update()
{
//
}
public function destroy(Model $model)
{
//
}
}
I have a simple code that displays to the user all of his notifications received from the Database:
$user_notifications = DB::table('notifications')->where('user_id', $this->user->id)->orderBy('id', 'desc')->get();
the problem is that I have too many controllers and functions in them and I don’t want to duplicate this code everywhere, in each function and controller. How can I make the $user_notifications variable global and use it everywhere?
u need to create a NotificationRepository
class NotificationsRepository
{
private Notifications $model;
public function __construct(Notification $model)
{
$this->model = $model;
}
public function findByUserId(int $userId): Collection
{
return $this->model->where('user_id', $userId)->orderBy('id', 'desc')->get();
}
}
Then in Controller action add this repository by autowiring
class SomeController extends Controller
{
public function someAction(NotificationRepository $repository, int $id)
{
$notifications = $repository->findByUserId($id);
}
}
or this way, i dont know how did u use your actions
class SomeController extends Controller
{
public function someAction(NotificationRepository $repository, Illuminate\Http\Request $request)
{
$notifications = $repository->findByUserId($request->user()->id);
}
}
I stumbled upon different articles about implementing Repository pattern in Laravel and all of them making me confused. Everyone of them is putting their weight on "keeping it ORM independent" but no one is actually showing the example code.
I am here with my repository sample structure which I believe is not ORM independent in a way. But I need it with REAL REPOSITORY PATTERN solution where I can change the ORM from Eloquent model to something else like Doctrine. And keep the Business logic separate some way so i no need to change it. currently my Business logic lies in Repository (not recommended i think.)
Basic Questions:
My repository, uses Eloquent method name inside it which will not be there if i change the ORM. $this->model = $shops;
In Controllers and Blade templates what we are playing with is Collections of Eloquent Model. How should we handle them if we change the ORM?
Where to put create/delete methods if not in repository.
Please don't just use Domain Object word because I am tired of
understanding it without an coded example. It will be highly
appreciated if you try to explain [Domain object] using a real code
example by modifying this. [How to return it in controller and use it
in Blade]
Interface:
<?php
namespace Modules\ShopOwner\Entities\Repository\Contract;
interface ShopsRepository {
public function getall();
public function create($data);
public function update($id, $data);
public function delete($id);
}
Eloquent:
<?php
namespace Modules\ShopOwner\Entities\Repository\Eloquent;
use Illuminate\Database\Eloquent\Model;
use Modules\ShopOwner\Entities\Repository\Contract\ShopsRepository;
use Modules\ShopOwner\Entities\Shops;
class ShopsEloquent implements ShopsRepository
{
protected $model;
public function __construct(Shops $shops)
{
$this->model = $shops;
}
public function getall()
{
return $this->model::with('shopadmin')->get();
}
public function create($data)
{
$this->model::create($data);
}
public function update($id, $data)
{
$this->model::findOrFail($id)->update($data);
}
public function delete($id)
{
$this->model::findOrFail($id)->delete();
}
}
Controller:
<?php
namespace Modules\ShopOwner\Http\Controllers;
use App\Http\Controllers\Controller;
use Auth;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Modules\ShopOwner\Entities\Repository\Contract\ShopsRepository;
use Modules\ShopOwner\Entities\Shops;
use Validator;
class ShopsController extends Controller
{
protected $shops;
public function __construct(ShopsRepository $shops)
{
$this->shops = $shops;
}
public function index()
{
$shops = $this->shops->getall();
return view('shopowner::shops.list', compact('shops'));
}
public function store(Request $request)
{
$data = $request->all();
$this->shops->create($data);
return redirect()->route('SO.shops.index')->with('success', __('shopowner::shops.create_success'));
}
public function update(Request $request, $id)
{
$data = $request->all();
$this->shops->update($id, $data);
return redirect()->route('SO.shops.index')->with('success', __('shopowner::shops.update_success'));
}
public function delete($id)
{
$this->shops->delete($id);
return redirect()->route('SO.shops.index')->with('success', __('shopowner::shops.remove_success'));
}
}
Create a base repository first. then extend this repository. Try this way. It may help you
interface BaseRepository{
public function getall();
public function create($data);
public function update($id, $data);
public function delete($id);
}
class BaseEloquent implements BaseRepository{
protected $model;
public function getall(){
return $this->model->get();
}
....
....
}
interface ShopsRepository extends BaseRepository{
}
class ShopsEloquent extends BaseEloquent implements ShopsRepository{
public function __construct(Shops $shops){
$this->model = $shops;
}
public function getall(){
return $this->model::with('shopadmin')->get();
}
}
I am new to laravel. I am having a doubt how to call other function inside the same controller and return the processed values to the function by which it has been invoked. I have tried this similar to C language but the code doesn't works
class AgreementsApiController extends Controller
{
public function store($th_id,$mv_id,$wk1_terms,$wk2_terms,$wk3_terms)
{
//make a function call here to add function similar to
$result=add($th_id,$mv_id);
}
public function add($th_id,$mv_id)
{ //process the parameters and return to store function
$r=$th_id+$mv_id;
return $r;
}
}
In your store function
$result=$this->add($th_id,$mv_id);
and thats it.
I want to use middleware in Usercontroller on only getDashboard() and getUserlist() method, but it didn't work for me.
also I add in controller constructor.
My Controller:
class Usercontroller extends Controller {
public function __construct() {
$this->middleware('auth',['only' => ['getDashboard']]);
//$this->middleware('auth');
}
##This method render home view.
public function index() {
// dd('yahoo');
return view('welcome');
}
##To add new user.
public function getAdduser() {
return view('register');
}
#To render dashboard view.
public function getDashboard() {
return view('dashboard');
}
When I directly type in url http://localhost/rabble/index.php/user/dashboard.it still display display without authenticate user is login or not.