Can't access specific route in Laravel - php

When I return from a function with a view and a compact table:
$table = (new \Okipa\LaravelTable\Table)->model(Expense::class)->routes([
'index' => ['name' => 'admin.expenses.index'],
'edit' => ['name' => 'admin.expenses.edit'],
'destroy' => ['name' => 'admin.expenses.destroy'],
])->tbodyTemplate('bootstrap.expenses.tbody')
->query(function($query) use($user){
$query->select("expenses.*");
// $query->join('projects',"projects.id","=","expenses.project_id");
// $query->addSelect('projects.name as project');
$query->where('user_id', $user->id)->whereNull('travel_id');
});
return view('backend.expenses.index', compact('table'));
Laravel displays this error:
Return value of Okipa\LaravelTable\Table::render() must be of the type string, object returned (View: /home/armand/Desktop/GSurvey/expenses/resources/views/vendor/laravel-table/bootstrap/table.blade.php)
The index blade is where it supposed to be and in the view I have just a simple line to display the table: {{ $table }}
Can anyone extend a helping hand, maybe I am missing something?
Thank you in advance,
Kind regards,
Armand Camner

Related

Laravel 9: testing get profile (by slug) for created row

I wrote test:
public function test_hello_world(){
$test = User::create(['name' => 'Test',
'email' => 'test#test.com',
'password' => 'password',
]);
Profile::create([
'user_id' => $test->id,
'name' => 'Test',
'slug' => 'test'
]);
$this->get('/profile/test')
->assertStatus(200);
}
What this code should testing? After get to this url it should display details about profile. If profile with this slug doesn't exist, we have error 404. In this test I create user and profile table (this 2 tables is connection) but after run test I have the error:
Expected response status code [200] but received 404. Failed
asserting that 200 is identical to 404.
Why I have this error since I created profile with this slug? For me the best option will be create testing database with a lot of records and conduct all test on it. Is it possible? How do that?
#Edit
I have a route and controller's method which display user's profile. If I go (in web browser) to localhost/profile/slug, it works, if this profile exist. My controller's method look like this:
public function show($slug) {
$profile = Profile::where('slug', $slug)
->firstOrFail();
return Inertia::render('Profile/Single', [
'profile' => $profile,
]);
}
And route:
Route::get('/profile/{slug}',
[ProfileController::class, 'show'])
->name('profile.show');
According to your requirement you have to create route for getting profile from slug name. You did wrong in single function. Without creating route it will not worked.
So below example may work for you.
For example:-
For creating data
public function createData(){
$user = User::create(['name' => 'Test',
'email' => 'test#test.com',
'password' => 'password',
]);
Profile::create([
'user_id' => $user->id,
'name' => 'Test',
'slug' => 'test'
]);
return redirect()->back()->with('success', 'Data created');
}
For Getting Data
public function getDataBySlug($slug){
$profile = Profile::where('slug',$slug)->firstOrFail();
return redirect('/dashboard')->with('slug', $slug);
}
In route file
you have to mention table name and column name {profile:slug} instead of id
Route::get('/profile/create', 'Controller#createData');
Route::get('/profile/{profile:slug}', 'Controller#getDataBySlug');
Your route definition is wrong please do as above

Return only certain data in from a collection - Laravel

I'm learning Laravel and have created a public endpoint where I want to output only certain information of some comments if a user is not authenticated from a GET request.
I have managed to filter out the comments based on whether or not they are approved. I now want to filter out the data that is returned. I have attached a screenshot of what is currently returned.
Ideally, I only want to return the id, name and the body in the json. How can I go about this? I tried the pluck() method which did not give the desired results. Any pointers would be greatly appreciated
public function index(Request $request)
{
if (Auth::guard('api')->check()) {
return Comment::all();
} else {
$comments = Comment::where('approved', 1)->get();
return $comments->pluck('id','name','body');
}
}
To select the particular columns, you can pass columns name to get as
$comments = Comment::where('approved', 1) -> get(['id','name','body']);
You can use a transformer to map the incoming data to a sensible output based on the auth state. The following example comes from the Fractal lib:
<?php
use Acme\Model\Book;
use League\Fractal;
$books = Book::all();
$resource = new Fractal\Resource\Collection($books, function(Book $book) {
return [
'id' => (int) $book->id,
'title' => $book->title,
'year' => $book->yr,
'author' => [
'name' => $book->author_name,
'email' => $book->author_email,
],
'links' => [
[
'rel' => 'self',
'uri' => '/books/'.$book->id,
]
]
];
});
Ideally, you would create 2 classes that extend from Transformer and pass the correct one to the output.
If you want to pass the result as json respose
$comments = Comment::where('approved', 1)->pluck('id','name','body')->toArray();
return Response::json($comments);
If you want to pass the result as to blade
$comments = Comment::where('approved', 1)->pluck('id','name','body')->toArray();
return view('your_blade_name')->with('comments',$comments);

Why the changes function does not return the changes?

652/5000
I am using in my project of Laravel 5 the package https://github.com/spatie/laravel-activitylog in its version 2.3. I have a page where I go through a list of activities and try to get the changes but it returns an empty array.
This is my Controller
public function history($id) {
$incidence = Incidence::find($id);
$activities = Activit::where('subject_id', $incidence->id)->get ();
return view('incidence.history', compact('activities'));
}
This is my html page
#foreach ($activities as $activity)
<p> {{ $activity->created_at }} </p>
<p> {{ $activity->changes() }} </p>
#endforeach
And this is the output in the browser
Clarify that I have done 4 update to the same record which I see reflected in the activity_log table of the database that uses the package. But I do not understand why the arrangement of the changes is not shown as indicated by the site's documentation:
Calling $ activity-> changes will return this array:
[
'attributes' => [
'name' => 'updated name',
'text' => 'Lorum',
],
'old' => [
'name' => 'original name',
'text' => 'Lorum',
],
];
Since it uses a database table I'm certain this has to do with the way Laravel allows methods to be chained. When you do $activity->changes() it expects you to continue the query. IE: $activity->changes()->where('etc', 1)->get() or something similar. So by calling $activity->changes() you are just sending a partial query to eloquent.

laravel 5 route passing two parameters

i have this route
Route::get('/artist/{id}/{name}', 'HomeController#artist')->where(['id' => '[0-9]+', 'name' => '[a-z]+'])->name('artist');
and this is my link
{{$artist->name}}
and this is the artist method on HomeController
public function artist($id, $name){ $artist = Artist::where('id', $id)->where('name', $name)->first();
return view('front.artist', compact('artist'));
}
i donot know this display error. this is the error. so please any one help me with this. iam in the middle of learning laravel.
ErrorException in UrlGenerationException.php line 17:
Missing required parameters for [Route: artist] [URI: artist/{id}/{name}]. (View: C:\xampp\htdocs\laravel\resources\views\front\home.blade.php)
Yo must pass the parameters as array, see https://laravel.com/docs/5.4/helpers#method-route
route('artist',['id' => $artist->id, 'name' => $artist->name])
or you can use
{!! link_to_route('artist', $artist->name, ['id' => $artist->id, 'name' => $artist->name]) !!}

Get specified properties of a model all at once in Laravel

I want to pass some user data to a view so it can be displayed in the profile page. There is quite a lot of it but I don't want to just pass everything, because there are some things the view shouldn't have access to. So my code looks like this:
return view('profile', [
'username' => Auth::user()->username,
'email' => Auth::user()->email,
'firstname' => Auth::user()->firstname,
'country' => Auth::user()->country,
'city' => Auth::user()->city->name,
'sex' => Auth::user()->sex,
'orientation' => Auth::user()->orientation,
'age' => Auth::user()->age,
'children' => Auth::user()->children,
'drinking' => Auth::user()->drinking,
'smoking' => Auth::user()->smoking,
'living' => Auth::user()->living,
'about' => Auth::user()->about,
]);
My question is: Can this be written shorter/simpler?
Thanks!
EDIT:
I don't want this: {{ Auth::user()->firstname }} because there is a logic in a view, which is bad - I think, there should be just plain variables to be displayed, in view, not anything else.
So I'm looking for something like:
return view('profile', Auth::user()->only(['firstname', 'email', ...]));
You could create by yourself a method named like getPublicData and then return all those properties you need.
...
public function getPublicData() {
return [
'property_name' => $this->property_name
];
}
...
... and then use it in your controller/views. Maybe it's not an optimal solution, but you can isolate this thing in the model and avoid too much code in the controller.
Another advanced approach could be the override of the __get method. However, I am not the first in this case.
Hope it helps!
You don't need to pass these variable to the view, you can directly access them in the view using blade
<h1>{{ Auth::user()->username }}</h1>

Categories