How pass Dynamic variable from url in Laravel - laravel

I need to fetch the data from database and display it view .
This is my web.php
Route::get('/businesscard/{name}', function ($name) {
//$username= App\users::where('username', $name);
$username=DB::table('users')->select('*')
->where('username', '=', $name)
// ->groupBy('status')
->get();
return view('auth.pro')->with(['username' => $username]);
return array(
'name' => $name
);
});
If the user enters domain.com/businesscard/username I need to fetch the data for the username and display it in view .It is working.But I need to remove businesscard .User need to enter domain.com/username. I have tried the below code.
Route::get('/{name}', function ($name) {
//$username= App\users::where('username', $name);
$username=DB::table('users')->select('*')
->where('username', '=', $name)
// ->groupBy('status')
->get();
return view('auth.pro')->with(['username' => $username]);
return array(
'name' => $name
);
});
If there is data it is working .but other pages are not working like login and register .Users are entering their username in registration .

The order of your route matters. See order of route declarations in laravel package
So the /{name} should be registered as the last route to avoid matching for other routes.

/{name} it means / with any value. If you try /login or /register.Then your logic is confused with this so that other pages are not working. Best way to develop as you expect like first one.
Another thing in your code there is two return second one is not doing anything. After the first one it return to view so second one unused. remove that return as well.

Related

Relationship User and children data using belongsTo

public function children()
{
return $this->belongsTo('App\User', 'parent_id', 'id');
}
$item = Item::where([
'status' => '1',
'id' => $id
])->first();
$user = User::where([
id=>Auth::id()
])->with('children')->get()
return view('item.list')->with(compact('item', 'user'));
How can I get item and authenticated user along with children and send it to view in one query or is there any other best practise.
From your code, it looks like Item is not related in any way to the User model. If that is the case, there is likely no reason to try to do this in one query, and likely not efficient or even possible. There could be some relation that I don't know of, but you are probably better off doing the two queries.. One for the $item:
$Item = Item::where([
'status' => '1',
'id' => $id
])->first();
And then one to load the children on the User object. This one is potentially a little different. If you are manually loading the User object for some reason, you can eager load the children:
$user = User::where([
'id' => $someId
])->with('children')->first();
If you are within the auth middleware, you don't need to re-load the user, it is already provided by Laravel. You can just load the children if they are not already there:
$user->load('children');
or, even easier, from your blade page, just call the load on the page:
$user->children();
You have the code correct for sending to your view:
return view('item.list')->with(compact('item', 'user'));

How to queue the logics in controller

I have used two logic in my controller in my laravel project
public function multiStore()
{
$user = User::create([
'name'=>$request->name,
'email'=>$request->email,
'password'=>Hash::make($request->name),
]);
$post = MyPost::create([
'name'=>$request->post_name,
'body'=>$request->post_body,
]);
return redirect()->to('/admin/home);
}
Is it possible to make like if user is created successfully only then the post will be created so that I can use post created by user relationship
I have tried something like if condition but it is not working
You can try the code bellow , I assume you have a user_id field in posts table since you mentio9ned a relation ship. This is not the best way but i try to keep things simple, so I just edited the code.
Note : make sure you listed all the table fields in protected $fillable in your model before using Create()
public function multiStore()
{
$user = User::create([
'name'=>$request->name,
'email'=>$request->email,
'password'=>Hash::make($request->name),
]);
if($user){
$post = MyPost::create([
'user_id' => $user->id
'name'=>$request->post_name,
'body'=>$request->post_body,
]);
}
return redirect()->to('/admin/home);
}
Enclose your query in database transaction
https://laravel.com/docs/5.8/database#database-transactions
Either you can:
DB::transaction(function() {
Model::create();
AnotherModel::create();
});
Or you can use the following to find and catch error...
DB::beginTransaction();
// Your queries here...
// Model::create();
// AnotherModel::create();
DB::commit();

Query returning every row null in laravel

I'm trying to build a chat application using laravel echo and pusher, everything works but the data that returns to the databse is either null or the default value, here's the code
public function sendMessage(Request $request){
$conID = $request->conID;
$message1 = $request->message;
$user = Auth::user();
$fetch_userTo = DB::table('messages')
->where('conversation_id', $conID)
->where('user_to', '!=', Auth::user()->id)
->get();
$userTo = $fetch_userTo[0]->user_to;
$message = Message::create([
'user_from' => Auth::user()->id,
'user_to' => $userTo,
'conversation_id' => $conID,
'message' => $message1,
]);
if($message) {
$userMsg = DB::table('messages')
->join('users', 'users.id','messages.user_from')
->where('messages.conversation_id', $conID)->get();
broadcast(new MessagePosted($message))->toOthers();
return $userMsg;
}
}
NB: when i put insert() instead of create in the query the data goes through the database normally but there's an error in broadcasting
Have you tried to create a message like this? instead of using a model event?
$message = new Message;
$message->user_from = Auth::user()->id;
$message->$user_to = $userTo;
$message->conversation_id = $conID;
$message->message = $message1;
$message->save();
You have a lot more control this way, i.e
if($message->save()) { ... }
Or you could wrap the whole thing in a transaction?
Be sure your Message model allows the fields that you want to add in the $fillable array
Create method check fillable attributes into Laravel model. You have to write your all columns into fillable and then use create method.
Second solution is use Active Record technique. #Devin Greay answer is helpful to use Active record.
More information visit https://laravel.com/docs/5.6/eloquent#mass-assignment

Laravel cache::remember is returing object as an array

Laravel Cache::remember is returning a LengthAwarePaginator object as an array.
function getNotifications( $userID ) {
$values = Cache::remember('cache-key', 10, function() {
$query = DB::table( 'user_notifications' )
->leftJoin( 'notifications', 'user_notifications.notification_id', '=', 'notifications.id' )
->where( 'user_notifications.user_id', $userID )
->select( 'notifications.*' )
->orderBy('created_at', 'DESC')
->paginate(5);
return $query;
});
return $values;
}
If I dd($query) before returning from Cache closure, it's returning the following object, that accepts $value->links() to display pagination.
But whenever the Cache is storing $query into $values it's returning values as an array:
I tried commenting out the unserialize-block:
/*foreach( $values as $key => $value ) :
$values[$key]->meta = self::maybeUnserialize($value->meta);
endforeach;*/
and confirmed that, that's not the cause.
I also tried, but failed:
$values = collect($values);
With multiple check and cross-check I am confirming that, the issue is the Cache::remember.
How can I force the Cache::remember return things as it is? So that I can let $object->links() work for me.
The actual code can be found here.
The issue is, Cache is made to store data, not the instance. So there are two ways to do this:
When caching, cache information per page, or
Get all the data while fetching, but make your own pagination
Solution 1:
We went for the second. But in case you need to go for the first solution, here's the code, I got from Laracasts, provided by chrisml:
$statuses = Cache::remember("statuses_{$id}_page_{$page}", 3, function() use ($event, $sort) {
return $event->statuses()
->with('comments')
->latest()
->paginate(10);
});
On the above code, the cache key is changing on every page, so the cache is storing per page.
Solution 2:
But for my case, we thought we should go for the second, and that would be wise for us, in our case. So, we've to make our own pagination. My luck that psampaz did the base for us on their blog:
Custom data pagination with Laravel 5 — by psampaz
So, instead of using ->paginate() we're fetching all the data first, and caching them as previous.
$values = Cache::remember('cache-key', 10, function() {
$query = DB::table( 'user_notifications' )
->leftJoin( 'notifications', 'user_notifications.notification_id', '=', 'notifications.id' )
->where( 'user_notifications.user_id', $userID )
->select( 'notifications.*' )
->orderBy('created_at', 'DESC')
->get(); // <----------- here
return $query;
});
But before returning the $values, we're making our own pagination. We made some fixes to the psampaz's code:
use Illuminate\Support\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
function getNotifications( $userID ) {
// Collapsed the cached values here :)
$values = Cache::remember('cache-key', 10, function() {...});
// Get current page form url e.g. &page=6.
$currentPage = LengthAwarePaginator::resolveCurrentPage();
// Get current path.
$currentPath = LengthAwarePaginator::resolveCurrentPath();
// Create a new Laravel collection from the array data.
$collection = new Collection($values);
// Define how many items we want to be visible on each page.
$perPage = 5;
// Slice the collection to get the items to display on the current page.
$results = $collection->slice(($currentPage - 1) * $perPage, $perPage)->all();
// Create our paginator and pass it to the view.
$values = new LengthAwarePaginator($results, count($collection), $perPage, $currentPage, ['path' => $currentPath]);
return $values;
}
And finally, we can easily use the $object->links() for pagination, and it's awesome! :)

Redirecting to view files

just wanted to firstly note is that this works fine when I have the redirects within their own retrspective functions.
Essentially, I create a Project. Within a Project I can make many types of Documents. Relationships are all set up appropiately.
So within a Project I have links to different documents which can be created. These are like
<li>{!! link_to_route('projects.document.create', 'Some Document', array($project, 'someDocument')) !!}</li>
The route is like this
Route::get('projects/{projects}/document/{name}', array('as' => 'projects.document.create', 'uses' => 'DocumentController#create'));
And then in my DocumentController I do this
public function create(Project $project, $name)
{
$this->redirectResult($project, $name);
}
The redirectResult function essentially checks to see if the selected document (in this case someDocument) has been created before (A project can have many documents, but only one of each type).
If the document has never been created for the project, it shows the create view for that document. If it has been created before it shows the edit view. This is the function
public function redirectResult(Project $project, $name) {
$selectedDoc = Document::where('project_id', '=', $project->id)
->where('name', '=', $name)
->first();
if(!$selectedDoc) {
return View::make($name.'.create', compact('project'));
}
else {
return View::make($name . '.edit', compact('project', 'selectedDoc'));
}
}
Now when I select a document, I end up on a blank page. The url is correct, no errors or anything, simply a blank page. The strange thing is when I do it the old way (which should act the same as the above)
it works. The old way is exactly the same as above, but my create function is like this instead
public function create(Project $project, $name)
{
$selectedDoc = Document::where('project_id', '=', $project->id)
->where('name', '=', $name)
->first();
if(!$selectedDoc) {
return View::make($name.'.create', compact('project'));
}
else {
return View::make($name . '.edit', compact('project', 'selectedDoc'));
}
}
So the only different is that the view making code is directly within the function, rather than calling a function that has this code. I wanted to put all this repeat code in its own function so I do not
have to repeat it for every document controller function.
Is there any reason why my new way takes me to a blank page? Just to rule out the obvious, I do have the folders containing the view files set up correctly. So for the above example within the views folder
I have a folder called someDocument and within it I have edit.blade.php.
Any information as to why this might be occuring appreciated.
Thanks
Er... you must return the function.
public function create(Project $project, $name)
{
return $this->redirectResult($project, $name);
}

Resources