Laravel, first() vs loop - laravel

I have an object on which I can run first() but I don't know how to loop through it.
$types = $biz->types()->first();
echo $types->name; //works great and gives me the name
This works fine but if I try:
$types = $biz->types(); //returns a BelongsToMany object
foreach($types as $type){
echo $type->name; //doesn't enter the loop at all
}
Edit: the following wouldn't work:
$biz->types; //returns an empty collection
This one doesn't give me anything and loop wouldn't initiate.
My question: How do I loop through $types and not just the first one?
PS: I wanted to focus on the loop and first so I didn't bring all the details.

You should access it as a property, which gives you access to the Collection of models. Accessing it as a method gives you QueryBuilder as a result.
foreach($biz->types as $type) {
...
}

Related

How to apply an operation/functionality on one column during getting data of a table in Laravel Controller?

I want to get all the data of today's Date, but during getting it I want to apply an operation on the data of one column only NOT others. This operation is from another function.
$data = Net::whereDate('created_at', Carbon::today())->get();
I have two options:
During getting data, call to that function on the specific column
After getting data, put a loop and then apply that operation and save data into new object
In this table, there is a column called profit, and I want to encode this profit into alphabets by calling encode_code() function remaining the other data as it is.
I don't know how I can do this, please help me if anyone knows.
You can use a foreach loop to get each object from the collection and for each of those object,call the desired function.
$data = Net::whereDate('created_at', Carbon::today())->get();
foreach($data as $key => $dat)
{
$data[$key]->profit = encode_code($dat->profit);
}
I think you should call the function and turn it like this
I just didn't know what you wanted to do, so this is my best
$data = Net::whereDate('created_at', Carbon::today())->get();
foreach($data as $i => $d){
$data[$i]->profit = encode_code($d->profit);
}
Of course you could loop through your result and encode each row, but this would prevent you from reusing this code.
Instead you could put that encode function directly into the model, so that you can reuse it everywhere:
public function getEncodedProfit() {
return encode_code($this->profit);
}
Now you can just use this function everywhere in your controllers or views like that:
echo $net->getEncodedProfit();

How to apply And where condition in orWhere?

I want to display data from cv table where user_id is $request->id.
Also, filtering is done so i have to put lots of orWhere.
Because of this my code is not working as expected.
Sorry question is a little bit confusing.
$search = $request->input('search.value');
$results = cv::with(['industrySegments','jobLocations','jobPositions','languages'])->where('user_id',$request->id);
$results->orWhere('name','LIKE',"%{$search}%");
$results->orWhere('gender','LIKE',$search);
$results->orWhere('contact','LIKE',$search);
$results->orWhere('contact2','LIKE',$search);
This code doesn't work.
whenever i type something in search button it displays data that is not supposed to be display.
I want to display only the data whose user_id is $request->id.
i think what you wanted to do is advanced where
your query will be like this
$results = cv::with(['industrySegments','jobLocations','jobPositions','languages'])->where('user_id',$request->id)->where(function($q)use($search){
$q->where('name','LIKE',"%{$search}%")->orWhere(..........;
})->get();
therefore you can play around with where / orWhere
Test next code:
$results = cv::with(['industrySegments','jobLocations','jobPositions','languages']);
if(!empty($request->id))
{
$results->where('user_id',$request->id);
}
else
{
$results->orWhere('name','LIKE',"%{$search}%");
$results->orWhere('gender','LIKE',$search);
$results->orWhere('contact','LIKE',$search);
$results->orWhere('contact2','LIKE',$search);
}

Remove Limit From Eloquent Query

How can I remove the limit/offset from the below query?
$query = TestModel::where('a', 'b')->limit(100);
$query->removeLimit();
I'm using a query from another module and I don't want to change the code.
You can reset the $limit property:
$query = TestModel::where('a', 'b')->limit(100);
$query->limit = null;
$unlimited = $query->get();
$query->getQuery()->limit = null;
One can reset the limit by passing the null value to the limit method.
$query->limit(null);
Works both with Eloquent\Builder and Query\Builder.
The simple answer to your question is - you cannot. Because you have already filtered the result set to a limit of 100 tuples.
What is the reason for you to avoid the change in code in the Model? Because what #Dhruv has suggested is the correct way to achieve what you want to.
In fact, if you still want to keep the code intact. You can rather define another function in your model this way and use it internally in your old function:
public function newFunction(){
return TestModel::where('a', 'b')->get();
}
public function oldFunction(){
return $this->newFunction()->limit(100);
}
Keeping your code consistent, then use newFunction() in your Controller to do whatever you want to.
get(): To get all record from table use get():
$query = TestModel::where('a', 'b')->get();
limit(): To limit the number of results returned from the query
$query = TestModel::where('a', 'b')->limit(10)->get();

Undefined property: Illuminate\Support\Collection::$election_name in view

In the controller, I store some data in an array.Then I want to send it in myelectionlist.blade.php
$my_election=[];
$i=0;
foreach ($election_list as $election_list)
{
$my_election[$i]=DB::table('election')
->where('id','=',$election_list->election_id)
->get();
$i++;
}
return view::make('myelectionlist')->with('election_list',$my_election);
I check with
return $my_election
It works fine. But In myelectionlist.blade.php when I write
#for($i=0;$i<sizeof($election_list);$i++)
{{$election_list[$i]->election_name}}
#endfor
It does not work.
Undefined property: Illuminate\Support\Collection::$election_name
happens, How to solve the problem?
There's a combination of problems that I would fix in order to bring clarity to your code and explain to you the problem. First of all in your code you have:
foreach ($election_list as $election_list)
I'll rename the variable for you to see:
foreach ($foo as $foo)
So what this does is that inside the foreach loop you will get all the values one by one, like expected but every time you store it to the initial variable. And once you are done with the foreach or break out of it earlier the $election_list will have the last used value. It might have unexpected results if you're trying to use the same $election_list later again. So I would suggest to use a differet variable names perhaps like $election_list as $election
Next, it's a little bit unclear why you would track the $index of the new elements by yourself. Instead you could just push into the array like this:
$my_election[] = $newObj
Actual error message:
Now for the actual error message: ->get() returns a Collection. So in the end you have an array full of Collections. So inside the for loop when you do $election_list[$i] - this will actually be a Collection object instead of the Model and thus the exception.
->get() will always get you the collection. For example with methods like ->first() and find/findOrFail you would get a single model. These functions might also be more appropriate to use since we are requesting with and id anyway.
Additionally, if this question is not a simplified version of your code then what I think you should actually do inside the controller:
$my_election = DB::table('election')
->whereIn('id', $election_list->pluck('election_id')) // pluck will give all the id's
->get();
This way you have a Collection of models assigned to $my_election.

Eloquent Collection: Counting and Detect Empty

This may be a trivial question but I am wondering if Laravel recommends a certain way to check whether an Eloquent collection returned from $result = Model::where(...)->get() is empty, as well as counting the number of elements.
We are currently using !$result to detect empty result, is that sufficient? As for count($result), does it actually cover all cases, including empty result?
When using ->get() you cannot simply use any of the below:
if (empty($result)) { }
if (!$result) { }
if ($result) { }
Because if you dd($result); you'll notice an instance of Illuminate\Support\Collection is always returned, even when there are no results. Essentially what you're checking is $a = new stdClass; if ($a) { ... } which will always return true.
To determine if there are any results you can do any of the following:
if ($result->first()) { }
if (!$result->isEmpty()) { }
if ($result->count()) { }
if (count($result)) { }
You could also use ->first() instead of ->get() on the query builder which will return an instance of the first found model, or null otherwise. This is useful if you need or are expecting only one result from the database.
$result = Model::where(...)->first();
if ($result) { ... }
Notes / References
->first() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_first
isEmpty() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_isEmpty
->count() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_count
count($result) works because the Collection implements Countable and an internal count() method: http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_count
Bonus Information
The Collection and the Query Builder differences can be a bit confusing to newcomers of Laravel because the method names are often the same between the two. For that reason it can be confusing to know what one you’re working on. The Query Builder essentially builds a query until you call a method where it will execute the query and hit the database (e.g. when you call certain methods like ->all() ->first() ->lists() and others). Those methods also exist on the Collection object, which can get returned from the Query Builder if there are multiple results. If you're not sure what class you're actually working with, try doing var_dump(User::all()) and experimenting to see what classes it's actually returning (with help of get_class(...)). I highly recommend you check out the source code for the Collection class, it's pretty simple. Then check out the Query Builder and see the similarities in function names and find out when it actually hits the database.
Laravel 5.2 Collection Class
Laravel 5.2 Query Builder
I think you are looking for:
$result->isEmpty()
This is different from empty($result), which will not be true because the result will be an empty collection. Your suggestion of count($result) is also a good solution. I cannot find any reference in the docs
I agree the above approved answer. But usually I use $results->isNotEmpty() method as given below.
if($results->isNotEmpty())
{
//do something
}
It's more verbose than if(!results->isEmpty()) because sometimes we forget to add '!' in front which may result in unwanted error.
Note that this method exists from version 5.3 onwards.
There are several methods given in Laravel for checking results count/check empty/not empty:
$result->isNotEmpty(); // True if result is not empty.
$result->isEmpty(); // True if result is empty.
$result->count(); // Return count of records in result.
I think better to used
$result->isEmpty();
The isEmpty method returns true if the collection is empty; otherwise,
false is returned.
According to Laravel Documentation states you can use this way:
$result->isEmpty();
The isEmpty method returns true if the collection is empty; otherwise, false is returned.
I think you try something like
#if(!$result->isEmpty())
// $result is not empty
#else
// $result is empty
#endif
or also use
if (!$result) { }
if ($result) { }
You can do
$result = Model::where(...)->count();
to count the results.
You can also use
if ($result->isEmpty()){}
to check whether or not the result is empty.
so Laravel actually returns a collection when just using Model::all();
you don't want a collection you want an array so you can type set it.
(array)Model::all(); then you can use array_filter to return the results
$models = (array)Model::all()
$models = array_filter($models);
if(empty($models))
{
do something
}
this will also allow you to do things like count().
You can use: $counter = count($datas);
The in_array() checks if a value exists in an array.
public function isAbsolutelyEmpty($value)
{
return in_array($value, ["", "0", null, 0, 0.0], true);
}
You want to check these two cases of count().
#1
If the result contains only a single row (one record) from the database by using ->first().
if(count($result)) {
// record is exist true...
}
#2
If result contain set of multiple row (multiple records) by using ->get() or ->all().
if($result->count()) {
//record is exist true...
}

Resources