delete() not working on Eloquent in laravel - laravel

delete() not working on Eloquent in laravel and getting the call to member function error. Like is just a simple model.
$matchThese = ['snippet_id' => $snippet_id, 'user_id' => $user_id];
$likedsnippet = Like::where($matchThese)->get();
$likedsnippet->delete();

Is Like has a child, or attached relationship? If yes, you first need to detach the connection or delete the child object as well.
If Like is a simple object, is it exists at all?
Maybe the object with the conditions you are searching for does not exists. Try to dd the like object before the delete, or wrap it around with:
if(isset($likedsnippet))
{
$likedsnippet->delete();
}
Or you can try to delete the objects one by one using a foreach:
foreach($likedsnippet as $obj)
{
$obj->delete();
}

Eloquent's get method return an Collection instance and collections don't have delete method. You can rewrite the query like this:
Like::where($matchThese)->delete();
it looks like there are only one deleting model in your application, if it's So, you can use first method.
$likedsnippet = Like::where($matchThese)->first();
$likedsnippet->delete();

Related

Call to a member function first() on null

When I try to fetch my user data, I receive the error
Call to a member function first() on null
public function show($id) {
$user=User::findOrFail($id);
$employee = $user->employees->first();
return view('admin.profile')
->with(['employee' => $employee , 'user' => $user]);
}
The problem is probably in your User model.
Check that you have declared the employees relationship:
public function employees()
{
return $this->hasMany(Employee::class); // I'm assuming you have a Employee model with expected column names, but feel free to replace everything with what you actually have in your app
}
If the problem persists, edit your question with your tables structure and your models.
It's very useful to understand the difference between $user->employees and $user->employees().
$user->employees: returns a Collection of employee models, or null if none are found.
$user->employees(): returns a query builder instance that you can chain additional conditions to (where's, etc).
Both options have a first() option available to them, but one is using a Collection method, where the other is using the query builder method.
Some have already suggested this, and I will as well - the safer and simplest solution to your problem is to use the query builder version of the relationship, since there is no risk of the employees() result being null. It also has the added benefit of not needing to load the entire relationship into a collection just to get the first result.
In short: $user->employees()->first(); is the best way to go.

Laravel: retrieving one item from a relationship

I am using Laravel Eloquent to retrieve data from the database.
I want to get the related data as an object not an array ( whats inside the texts table), so it is easier to work on the data on the blade file. This is my code I tried using first() but it doesn't work
Icon::with(["texts" => function($query) use ($language){
$query->where("language_id",$language->id)->first();
}, "texts.language"])->get();
How to Acheive it?
You could create an accessor function that provides a shorthand attribute to the required value.
In your Icon class:
public function getTextAttribute() {
// You'd only have to provide the $language somehow.
return $this->texts()->where('language_id', $language->id)->first();
}
Elsewhere, like in Blade, when you're using an Icon you can then use:
{{$icon->text}}

Laravel different use of where clause

I want to ask about some feature in Laravel, I'm working with some old code written by someone else and I want to understand why it is written this way:
$users = Users::all();
$results = $users->where('age', '>','30')->get();
My question is how can 'where' clause be used with the '$users' variable? This works fine and no error is given and it returns the required results. But as far as i know, 'where' clause can be used like:
Classname::where()->get()
Does the User model implements some feature or use something to be able to call 'where' clause this way? When i try to do the same but with a new model i'm creating I get
"Type error: Too few arguments to function Illuminate\\Support\\Collection::get()
How can 'where' clause be used with the '$users' variable?
The where clause can be used because the all() method returns a Collection, and the where() and get() methods are available on the Collection class.
Does the User model implements some feature or use something to be able to call 'where' clause this way?
Each Eloquent model serves as a query builder which will make you able to add constraints and receive the results with the get() method afterwards.
// Collection::get() is diferent with QueryBuilder::get()
$builder = Users::query(); // you got QueryBuilder object
$builder->where('age', '>','30'); // you got QueryBuilder object
$list = $builder->get(); // you got Collection object
$list->where('age', '>','30'); // you got Collection object
// Collection object has 'get', but it require argument.
// QueryBuilder object has 'get' too, but do not require argument.

Laravel overwrite toArray with custom parameter

In my controller I have:
$Locations = Locations::where(something);
$Locations->get()->toArray(true);
And inside the model:
function toArray($include_all = false) {
var_dump($include_all);
}
The include all variable is false, although the function gets called.
Is there a reason why it's doing that ?
I want to call a custom toArray because I have more oneToMany relations with different structures that I want to change (some of them are serialized for example)
Thank you
You can use Illuminate\Support\Collection methods such as map() and filter() to modify the collection and at the end of that call toArray() method.
It would be fairly easy to overwrite, however I think there is some confusion that should be cleared up first.
First, the toArray() method you are calling in this case is on the Collection which is the object which is returned when you use get() on your model.
With that said, you can add the following to your Location model to return a custom collection...
public function newCollection(array $models = [])
{
return new CustomCollection($models);
}
Then you write the new CustomCollection class with appropriate namespaces just to make sure it gets auto loaded fine, have it extend \Illuminate\Database\Eloquent\Collection and then you can proceed to override the toArray method.
However, it feels like you randomly selected this toArray() as a proper candidate to perform your logic just because you are already using it. You should think about creating a new function which calls $this->toArray() to grab the results and modify them as you need and return that.
If you need this same functionality on other models, just keep adding that newCollection method where needed.
This is also in the docs as well, might be worth checking out...
https://laravel.com/docs/5.2/eloquent-collections#custom-collections

Cannot merge on an Eloquent collection in Laravel

I need to merge either a collection or an array (it can be either) in Laravel 5.1, but I am getting the error BadMethodCallException in Builder.php line 2071: Call to undefined method Illuminate\Database\Query\Builder::merge()
When I make a collection from scratch, I can merge to it, but I cannot merge onto the result of an Eloquent query, which I thought were collections as well. But perhaps that is not true?
Code that gives the error:
$user=User::where('user_last_name', 'Doe')->first();
$tomerge = collect(['book' => 'desk', 'foot' => 'chair']);
$newcollect = $user->merge($tomerge);
If I instead did $tomerge->merge($user) it works, but that's not what I actually need. Is there a way to use merge as I want?
To answer your question as to why it's not working...
$user = User::where('user_last_name', 'Doe')->first();
This is a single instance of a model. Not a collection. An eloquent model does not have the merge method.
If you want to append attributes to an Eloquent model, the simplest way is probably to use the $appends property and the appropriate accessor. For example, in your User model..
protected $appends = ['book', 'foot'];
public function getBookAttribute()
{
return 'desk';
}
public function getFootAttribute()
{
return 'chair';
}
However, note that this will affect every instance of your User model.

Resources