Is there a way to pass condition in eloquent that if key exists then don't send object from collection (in mongodb)? - laravel

I am using jenssegers/laravel-mongodb,
I have a collection segments, I don't want those objects to be send by eloquent which has key named 'unrooted' i.e. to pass a condition to check if 'unrooted' key is set in collection, so I want
$condition[' ? '] = false; // $condition unrooted exists is false.
$segments = Segment::where($condition)->get();
I know that it can be done like getting all the objects pass the condition, and then
foreach($segments as $key => $segment){
if(property_exists($segment, 'unrooted')){
unset($segments[$key]);
}
}
dd(array_values($segments->toArray());
But it is not efficient for me incase of large collection.
Thankyou for you help.

It was simple, just used mongodb docs, posting it here for future references.
$condition['$exists'] = false;
$exists does the trick.

Related

Eloquent model update returns true but db change not reflecting

I have a model called CustomerInfo and i am trying to update it. update returns true but the changes are not reflecting on my db.
$customerInfo = CustomerInfo::where('machine_name',$username)->firstOrFail();
$result = $customerInfo->update($data);
$data varaible is a array having key value pair.
Also tried the following
$customerInfo = CustomerInfo::where('machine_name',$username)->update($data);
make sure $data variable that you want update record by its values, not be same with that record.
in this case, you don't have sql error but return of update will be zero.
Solved my questions.
Thanks Luciano.
i started eloquent manual db transaction and forgot to commit it at the end
DB::beginTransaction();//did this
$customerInfo = CustomerInfo::where('machine_name',$username)->firstOrFail();
$result = $customerInfo->update($data);
DB::Commit() //forgot to implement this part.
$result = $customerInfo->update($data);
$result variable will return only the boolean value. Try to return $customerInfo i.e.
return response()->json($customerInfo);
This will help you to find the actual problem and make sure the CustmerInfo model contains fillable properties and the $data variable contains all the information.
Try to use dd() like below to identify the issue:
dd($variable);

Best approcah for getting the object in the foreach loop in laravel using eloquent?

I have some properties and i want to get the object for each property, currently, I am using the eloquent in the foreach loop like this as shown in the image that will describe the best..
but it is really not a good approach because if I have 100 published property I will making 100 calls to the DB... and that is not correct?
I need a suggestion and a proper solution to this query?
Thanks in advance
Before foreach you can get all the RentalProperty items from db like this:
$allRentalProperties = RentalProperty::all();
and in foreach loop you can get those items without connecting database like this:
$propertyObj = $allRenatalProperties -> where('id', $property['id']) -> first();
Also, you can use array shorthand.
$newArray = [];
it's much simple and readable.
You can do array pluck before loop:
$propertyIds = Arr::pluck($published_properties, 'id');
Then you can make a whereIn query to get only those data which are in $published_properties object
$propertyObj = RentalProperty::whereIn('id', $propertyIds);
Then you can access that object with id if you change array key with record id.

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 dissociate elements from a HasMany relation?

There's the save and saveMany methods on the HasMany relation class, but where are the dissociate(Many)/detach(Many) methods? There's also no built-in way to get the inverse relationship method, so what's the best way to dissociate an array of id's/models from a HasMany relationship object.
Currently I'm using:
$hasMany = $parent->theRelationship(); // Get the relationship object.
$child = $hasMany->getRelated(); // Get an empty related model.
$key = $hasMany->getForeignKeyName(); // Get the name of the column on the child to set to NULL.
$child->findMany($IDs)->each(function($model) use ($key) {
$model->$key = NULL;
$model->save();
});
This could be alot shorter with something like:
$hasMany = $parent->theRelationship();
$hasMany->dissociate($IDs);
Bonus points if you have any official answers from Taylor as to why he hasn't implemented this, I've seen him close feature requests of this kind on GitHub.
I am not sure why there isn't a function, but to be more performant than your example, you could use the DB class like:
\DB::table('child_table')->where('parent_id', $parent->id)->update(['parent_id' => null]);
You could use detach like so;
$parent->theRelationship()->detach([1,2,3])
Where you pass an array of IDs.
From Laravel documentation:
"For convenience, attach and detach also accept arrays of IDs as input"
The performatic way (1 db update):
$partent->theRelationship()->update(['parent_id' => null]);
The readable way (multiple db updates):
$parent->theRelationship->each->parentRelationship()->dissociate();

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