Laravel model:all, use results (collection) in the same function - laravel

I am retrieving events from DirtyEvent model and I want to create an Ical using the values from the results however it says that the values do not exist in currect collection:
public function handle()
{
$event = DirtyEvent::all()
->pluck('startdate')
->pluck('endate');
dd($event);
$vCalendar = new \Eluceo\iCal\Component\Calendar('http://localhost/test');
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent ->setDtStart(new \DateTime($event->startdate))
->setDtEnd(new \DateTime($event->endate));
$vCalendar->addComponent($vEvent);
dd($vCalendar);
}

DirtyEvent::all()
->pluck('startdate')
->pluck('endate');
What you're doing here is
Get all events
Pluck the startdate from the collection of those events
Try to pluck the enddate from the collection of plucked startdates
Instead, you should do e.g.
DirtyEvent::pluck('startdate', 'enddate')->all();
to get an array of dates, which you can then use to populate your data.

Related

How can I get the data inside my notifications from within my Controller?

I'm trying to get the numbers of records from my notifications, where the candidate_user_id column from inside the data attribute is the same as the UserId (Authenticated User).
After I dd, I was able to get the data from all of the records in the table by using the pluck method (Line 1). I then tried to use the Where clause to get the items that I need
but this just didn't work, it was still returning all of the records in the table.
DashboardController.php:
public function index()
{
$notifications = Notification::all()->pluck('data');
$notifications->where('candidate_user_id', Auth::user()->id);
dd($notifications);
}
Here is a partial screenshot of the data that is being plucked.
How can I get the data from this, in a way like this ->where('candidate_user_id', Auth::user()->id);?
If data was a JSON field on the table you could try to use a where condition to search the JSON using the -> operator:
Notification::where('data->candidate_user_id', Auth::id())->pluck('data');
Assuming you only want this data field and not the rest of the fields, you can call pluck on the builder directly. There isn't much reason to hydrate Model instances with all the fields to then just pluck a single field from them if it is just a table field, so you can ask the database for just the field you want.
The data in the data field is a json string, so you can tell Laravel to automatically cast it as an array using the $casts property on each of the models that is notifiable.
For instance, if you have a User model which uses the trait (ie has use Notifiable), add this:
protected $casts = [
'data' => 'array',
];
If you want to access all notifications for the auth user.
$user = auth()->user();
dd($user->notifications->pluck('data'));
If you really want to do in your question way, here is how.
$notifications = Notification::all()->pluck('data');
$notifications = $notifications->where('candidate_user_id', Auth::user()->id)
->all();
This assumes you that you did not modify the default laravel notifications relationship and database migration setup. If you have modified some of the default ones, you need to provide how you modify it.

Get specific values from controller function

I started learning Laravel and I am trying to achieve the following:
Get data from database and display specific field.
Here is my code in the controller:
public function show()
{
$students = DB::select('select * from students', [1]);
return $students;
}
Here is my route code:
Route::get('', "StudentController#show");
That all works for me and I get the following displayed:
[{"id":1,"firstname":"StudentFirstName","lastname":"StudentLastName"}]
How can I get only the "lastname" field displayed?
Thanks in advance!
DB::select('select * from students')
is a raw query that returns an array of stdClass objects, meaning you have to loop through the array and access properties:
$students[0]->lastname
You can also use the query builder to return a collection of objects:
$collection = DB::table('students')->get();
$student = $collection->first();
$student->lastname;
Lastly, using the query builder, you can use pluck or value to get just the last name. If you only have one user, you can use value to just get the first value of a field:
DB::table('students')->where('id', 1)->value('lastname');
I strongly advise you to read the Database section of the Laravel docs.
$students[0]['lastname'] will return the last name field, the [0] will get the first student in the array.
I would recommend creating a model for Students, which would make your controller something like this:
$student = Students::first(); // to get first student
$student->lastname; // get last names
If you only want the one column returned, you can use pluck()
public function show()
{
$last_names= DB::table('students')->pluck('lastname');
return $last_names;
}
This will return an array of all the students' lastname values.
If you want just one, you can access it with $last_names[0]
As a side note, your show() method usually takes a parameter to identify which student you want to show. This would most likely be the student's id.
There are several ways you can accomplish this task. Firstly, I advise you to use the model of your table (probably Students, in your case).
Thus, for example,to view this in the controller itself, you can do something like this using dd helper:
$student = Students::find(1);
dd($student->lastname);
or, using pluck method
$students = Students::all()->pluck('lastname');
foreach($students as $lastName) {
echo $lastName;
}
or, using selects
$students = DB::table('students')->select('lastname');
dd($students);
Anyway, what I want to say is that there are several ways of doing this, you just need to clarify if you want to debug the controller, display on the blade...
I hope this helps, regards!

Most efficient way to update related Model from event listener

I have two models Business and Products.
I have an event which fires whenever the price of a product changes, an event listener will calculate the min and max aggregate values of the businesses products and store them within the Business model (while I know this can be done dynamically, this is required for indexing and searches).
In my event listener handle I have the following:
public function handle(ProductModified $event)
{
$business = $event->product->business;
$aggregate_values = Product::join('business', 'product.business_id', '=', 'business.id')->where('business.business_id', '=', $business->id)->groupBy('business.business_id')->get(['product.business_id', DB::raw('max(product.price) as max_cost, min(product.price) as min_cost')]);
Log::info('aggregate values: ' . $aggregate_values);
$business->min_cost = $aggregate_values->min_cost;
$business->max_cost = $aggregate_values->max_cost;
$business->update;
}
Using the code above I receive the following error:
Property [min_cost] does not exist on this collection instance.
My understanding is that I'll have to do a Business:find() to initiate the model and then update it. Is yes, is there a more efficient way to do this as this will call another query? Otherwise could someone tell me the correct way to update the related model?
Actually, Query return Laravel Collection object instead Product Model object. In order to fetch property, you can simply use $aggregate_values->first()->min_cost
If it won't work, you can replace query with this one
$result = Product::select('product.business_id', DB::raw('max(product.price) as max_cost, min(product.price) as min_cost'))->join('business', 'product.business_id', '=', 'business.id')->where('business.business_id', '=', $business->id)->groupBy('business.business_id')->firstOrFail();
$business->min_cost = $result->min_cost;
$business->max_cost = $result->max_cost;
$business->save();
Most efficient way to update related model is by using Eloquent Relationship feature Documentation url

laravel access model properties

I am looking for solution how to access eloquent model items by 'alias' field.
There is no problem accessing items by 'id'. But building a custom query I find myself unable to access item properties.
This piece of code works perfect
$cat = Category::find(1);
return $cat->title;
But if I am querying items with any other argument - properties are inaccessible
This code
$cat = Category::where('alias','=','vodosnab')->get();
return $cat->title;
throws an exception
Undefined property: Illuminate\Database\Eloquent\Collection::$title
Could you please help.
You already got the answer but here are some insights, when you use get() or all(), it returns a collection of model objects, which is an instance of Illuminate\Database\Eloquent\Collection, so here you'll get a Collection object
$cat = Category::where('alias','=','vodosnab')->get();
Now, you can use, $cat->first() to get the first item (Category Model) from the collection and you may also use $cat->last() to get the last item or $cat->get(1) to get the second item from the collection. These methods are available in the Collection object.
Using the first() method like Category::where('alias','=','vodosnab')->first(); will return you only a single (the first mathing item) model which is an instance of your Category model. So, use all() or get() to get a collection of model objects and you can loop through the collection like:
foreach(Category::all() as $cat) { // or Category::get()
$cat->propertyName;
}
Or you may use:
$categories = Category::where('alias','=','vodosnab')->get();
foreach($categories as $category) {
$category->propertyName;
}
Also, you may use:
$categories = Category::where('alias','=','vodosnab')->get();
$firstModel = $categories->first();
$lastModel = $categories->last();
$thirdModel = $categories->get(2); // 0 is first
If you need to get only one then you may directly use:
$category = Category::where('alias','=','vodosnab')->first();
$category->fieldname;
Remember that, if you use get() you'll get a collection of Model objects even if there is only one record available in the database. So, in your example here:
$cat = Category::where('alias','=','vodosnab')->get();
return $cat->title;
You are trying to get a property from the Collection object and if you want you may use:
$cat = Category::where('alias','=','vodosnab')->get();
return $cat->first()->title; // first item/Category model's title
return $cat->last()->title; // last item/Category model's title
return $cat->get(0)->title; // first item/Category model's title
You may read this article written on Laravel's Collection object.
get() returns a Collection of items. You probably need first() that returns a single item.

Getting an indexed collection

I would like to get an indexed collection from an eloquent call to get a specific item:
$items = FeedItem::all();
$specific_item = $items[4];
Or is it possible to do something like:
$items->get('id', 4);
where id is the attribute and 4 is the value of the attribute.
FeedItem::all() will return a Illuminate\Database\Eloquent\Collection.
To get a specific model you can use the find method:
$items = FeedItem::all();
$item = $items->find($id);
For more methods of the Collection class see the docs and the api.

Resources