Laravel: Passing variable from Blade to relationship not working - laravel-5

I am trying to modify a Laravel relationship to return the related case against a question.
My question model has the following relationship entry:
/**
* A Question has one Case Detail
*
* #return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function casedetail( $caseId ) {
return $this->hasOne( 'App\CaseDetail' )->where( 'test_case_id', $caseId );
}
However, trying to access the casedetail from Blade using a variable like this:
{{ $Question->casedetail(2) }}
Is returning me the following error:
"htmlspecialchars() expects parameter 1 to be string, object given (View: /home/vagrant/Code/TestBench/resources/views/testcases/category_questions.blade.php)"
If I substitute $caseId for a specific number and remove the variable request from the method then my query works fine:
return $this->hasOne( 'App\CaseDetail' )->where( 'test_case_id', 2 );
Result:
{"id":1,"test_case_id":2,"question_id":1,"result_type":0,"result":"now what","tester_id":1,"attachment":null,"created_at":"2017-11-30 03:17:42","updated_at":"2017-12-04 06:57:40"}
I am trying to retrieve the specific CaseDetail from the database that relates to the question_id and test_case_id. So for each question, give me the related CaseDetail:
#foreach( $Category->Questions as $Question )
{{ $Question->casedetail( $TestCase->id ) }}
#endforeach

I think everything is correct. In this case, you calling relationship method. Every relationship method returns you object of a collection.
Might be a chance here blade need single property or string to print and method returns collection?
Have you tried like this:
{{ $Question->casedetail(2)->id }}
try to print single property hope it works.

Related

wanted to create route like this but not able to find exact parameter value in controller?

Having issue in slug1 and slug2
Route::get("/something/{slug1}-{slug2}-sample-sample" , "Controller#Method")->where(['slug1'=>'[a-z0-9-]+', 'slug1'=> '[a-z0-9-]+');
where slugs can be xxx-yyy or only xxx
I'm getting only one parameter value
Because you put slug1 twice in the where method, so your route is only checking against the first slug twice, also you forgot to close the array :
Route::get("/something/{slug1}-{slug2}" , "Controller#Method")->where(['slug1'=>'([\w]+[-]{1}[\w]+)', 'slug2'=> '([\w]+[-]{1}[\w]+)']);
If afterwards you want to get those values in your controller using your Method, you can pass those slugs in that method as a parameter:
public function Method($slug1, $slug2)
{
dump($slug1, $slug2); //will display both slug's value
}
If you want to pass them to your view :
public function Method($slug1, $slug2)
{
return view('your-blade-view', ['slug1' => $slug1, 'slug2' => $slug2]);
}
And to retrieve them from your view
{{ $slug1 }} //echo first slug
{{ $slug2 }} //echo second slug
Update : this is the REGEX you were looking for : ->where(['slug1'=>'([\w]+[-]{1}[\w]+)', 'slug2'=> '([\w]+[-]{1}[\w]+)']); see here.

How to get the value from Laravel Collection

I have a Model called OfficeHours which as various attributes and the model User belongsTo OfficeHours. I am trying to fetch a particular element from a collection but am getting blank in blade.
public function office_hours() {
return $this->hasMany(OfficeHours::class);
}
public function user(){
return $this->belongsTo(User::class);
}
In Blade when i do the following:
{{$logged_in_user->office_hours->where('dow',2)}}
it works and gets me the following collection:
{"2":{"id":3,"user_id":4,"dow":2,"fromtime":"07:00:00","totime":"16:00:00","created_at":"2019-01-31 14:48:32","updated_at":null}}
now how i do i get the elements of that collection?
i tried
{{$logged_in_user->office_hours->where('dow',2)->get('fromtime')}}
but it gives me blank
How do i access the elements?
To preface, you shouldn't be doing that kind of logic in the view file, this is what controllers are for. You'd be able to do $fromtime = ...; and pass that to the view via return view(...)->with(["fromtime" => $fromtime]);
But, that being said, you should be able to do
{{ $logged_in_user->office_hours->where("dow", 2)->first()->fromtime }}
Note you're gonna get an error if ->where("dow", 2) doesn't return a Collection, as null doesn't have a ->first() method on it.

Laravel htmlentities() expects parameter 1 to be string, array given after it's converted to string

Trying to set and get session in laravel. In my controller I'm converting an array to string which doesn't throw an error if printed, however froim the error looks like session is getting an array instead of a string. Controller:
public function getQuestions(){
$questions = DB::table('questions')->orderBy(DB::raw('RAND()'))->get();
$questions= json_decode(json_encode($questions), true);
Session::put('questions', $questions);
return view('test', array('questions' => $questions));
}
Blade:
{{ Session::get('questions') }}
An error:
htmlentities() expects parameter 1 to be string, array given
'questions' is collection of objects. You can't print objected directly using {{placeholder}}. Whenever you use {{ placeholder}} laravel blade engine assume that it is a string. So it passes that varaible through htmlentities functions. So the error comes. If you really need to print this, you can write a foreach loop. Here is sample
#foreach(Session::get('questions') as $question)
{{$question-> attribute _to_print}}
#endforeach
Blade tutorial
Blade {{ }} statements are automatically sent through PHP's htmlspecialchars function to prevent XSS attacks.

Switching from Limit() to First() in Laravel Model

I'm stuck on an issue where I'm trying to clean up code presented to me, and I feel like I must've just been at this too long and can't see this issue.
At the moment I have the following code in one of my models:
public function attachments(){
return $this->hasMany(volunteerAttachment::class, 'volunteerID','id');
}
public function photoID() {
$photoID= $this->attachments()->where('category','Drivers License')->orderBy('endDate','desc')->limit(1);
return $photoID;
}
What I would like to do is what I believed was relatively simple in replacing the limit(1) of the function photoIdentification with a simple first().
But when I try that and simply put {{$volunteer->photoID->id}} in my blade, it simply returns the error App\volunteer::photoID must return a relationship instance.
I do however know that there is a relationship because if I continue to use the limit(1) and put:
#foreach($volunteer->photoID as $id)
{{$id->id}}
#endforeach
It returns the relation and document correctly.
$volunteer is the variable for that particular model App\volunteer, and the following is how it is defined in the controller:
public function show(Volunteer $volunteer){
return view('volunteer.show', compact('volunteer'));
}
The function photoID() will still return a full volunteerAttachment object. If you want to get the id using the first() function you will have to select the id property on the object like so:
{{ $volunteer->photoID()->id }}
You could also create an accessor on the model that directly returns this property:
public function getPhotoidAttribute($value)
{
return $this->attachments()->where('category','Drivers License')->orderBy('endDate','desc')->first()->id;
}
Now in blade you can just use:
{{ $volunteer->photoid }}
When you call a function of a model as a variable Laravel assumes you try to return a related model. Try with an accessor instead:
public function getPhotoidAttribute($value) {
$photoID= $this->attachments()->where('category','Drivers License')->orderBy('endDate','desc')->first();
return $photoID->id;
}
and call it like this:
{{ $volunteer->photoid }}

Laravel Auth User

In my controller i'm doing
$user = Auth:user()->get();
dd($user);
This is giving me the list of all users from my database.
why?
The other answers either explain how to solve your problem but not properly why this happens.
The laravel documentation states (source):
The get method returns an Illuminate\Support\Collection containing the results where each result is an instance of the PHP StdClass object.
With the full documentation found here, with API references here.
In essence, the get function here returns a collection and not the User object. The get method on an QueryBuilder executes a select statement.
With the following snippet we can see what queries get executed.
DB::enableQueryLog();
Auth::user()->get();
dump(DB::getQueryLog());
This will output:
DB::enableQueryLog();
Auth::user()->where('id', 1)->get();
dump(DB::getQueryLog());
This will output:
The first query will indeed output the expected user, the second query will grab the user class from the Auth::user() and select all rows from that table.
When we execute the 3rd and 4th query we can see that we once more first get the expected user, the 4th query however does also get a user (in this case the user with id 1). This is due too the where and not the Auth::user().
What we can conclude from these results is that the get takes into account all query builder functions but not the parameters of the supplied class.
If you use a get on an object it will only take into account the Class of that Object.
As too solve your problem the other questions where correct and you can use:
$user = Auth::user();
To fetch the user.
Because get return collection
Laravel Doc
Just remove get() to get single user data
$user = Auth:user();
dd($user);
in this case get() method return user collection object
You can auth user data by :
$user = Auth::user(); instead of using get();
Your user id is: {{ $user->id }}
Your first name is: {{ $user->first_name }}
Your last name is: {{ $user->last_name }}
return User::where('id', auth()->id())->with(['something'])->first()

Resources