Laravel: retrieving one item from a relationship - laravel

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}}

Related

delete() not working on Eloquent in 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();

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!

Adding data to an eloquent collection?

Im getting various data out of my database.
Product::with('users');
I also have toe execute a complex raw query to get back some information. This is returned as an array.
In my method I would like to get products with users and then add on the data from my raw query to this collection, but this data comes back as an array. Something like:
Product::with('users');
Product->extraData = $rawQuery;
How can I add the raw query output to my Product Collection?
By using Eloquent Facade like Product:: you will get an Eloquent Model object as a result or an Eloquent Collection object as a result, including results retrieved via the get method or accessed via a relationship.
Now, if i understand correctly, you need to add a single extraData property to Eloquent Collection model alongside with Collection items? Or you need to add extraData for each Product ?
If you need to add additional property to Eloquent Collection object, maybe it is a good idea to use a Custom Collection. Please read this section: http://laravel.com/docs/5.1/eloquent-collections#custom-collections .
<?php namespace App;
use App\CollectionWithExtraData;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function newCollection(array $models = [])
{
return new CollectionWithExtraData($models);
}
}
And maybe your CollectionWithExtraData can have let's say a
public function setExtraData() {
}
or
public $extraData = array();
If you need extraData for each Product Eloquent Model, just create a new attribute within your Eloquent Model, make it public and set your extra data when needed. Make use of setExtraData() method and $extraData property from above

cakephp3.0 query Builder Retrieve data

Hey I am facing some problem I am trying to create a patientcontroller.php in which I want to get data for only one user id from users table so that I can create a dashboard for sngle patient here is my code :
PatientsController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Network\Exception\NotFoundException;
use Cake\ORM\TableRegistry;
class PatientsController extends AppController
{
public function isAuthorized($user)
{
return true;
}
public function index (){
echo $this->Auth->user('id');
$users = TableRegistry::get('Users');
$users->find('all')->where(['id' => 4]);
$this->set('users', $users);
}
I want to get username bio and profile information in my Index.ctp I am trying to pass data using query builder but I am confused so any help
So you have a number of issues with both your approach, techniques and also your code.
Methods
http://book.cakephp.org/3.0/en/controllers.html
If you want to get a single patients record, you should be using the view() method in your controller. So you need to create a new method called view(), in which you can return your record. This method should, in most cases, take an id as the parameter.
Tables
http://book.cakephp.org/3.0/en/orm/table-objects.html
In CakePHP the table which is associated with the controller will be loaded by default. So there is no need to use the TableRegistry to load the table.
Fetching data
http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html
When you are looking for a single record you have two choices. You can either just use a find, with a first().
$this->Patients->find()
->where(['id' => $id])
->first();
Or you can use get() which will throw an exception if a record isn't found.
$this->Patients->get($id);
Joining associated data
http://book.cakephp.org/3.0/en/orm/associations.html
If you want to join data to your user, then you'll need Tables to manage that data, which can then be contained, using foreign keys in your database. This will change your finds, to include a contain() call.
$this->Patients->find()
->where(['id' => $id])
->contain(['Profiles])
->first();
Outputting data in the view
You can set the result of your find to the view as you have done, and then you can loop through, or output it how you like, using the variable you've set. In your case $user.
Summary
So overall you can see that there is quite a bit you are missing. Hopefully this will help get you on track.
Given that this is basically your third question here asking for exactly the same thing (getting the results of a query) I will point you to these very useful resources that you should read:
The tutorials: http://book.cakephp.org/3.0/en/tutorials-and-examples.html
They basically have everything you need to understand how queries work and how they can be used in the view and forms.
The ORM manual: http://book.cakephp.org/3.0/en/orm.html
You will find plenty examples of getting data and using it after retrieving it.
I Found A solution for this query : Full code for this kind of problem :
PatientsController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Network\Exception\NotFoundException;
use Cake\ORM\TableRegistry;
class PatientsController extends AppController {
public function isAuthorized($user) {
return true;
}
public function index () {
$id = $this->Auth->user('id');
$articles = TableRegistry::get('Users');
$query = $articles->find()
->where(['id' => $id]);
$this->set(compact('query'));
}
}
For Index.ctp
<!-- File: src/Template/Articles/index.ctp (edit links added) -->
<h1>Patient Dashboard</h1>
I am patient
<?php
foreach ($query as $row) {
echo $row->username ,$row->password;
}
?>
This kind of solution is veryhelpful if you are just trying to move from procedural php to oops in cakephp .

Resources