Eloquent hasOne relationship Not working laravel 5.4 - laravel

I am trying to keep a relationship between two tables in my database.
Users Table:
Id User_id Name
Contacts Table:
Id User_Id contacts
I am saving multiple contacts in the contacts table. Now i want to retrieve all the contacts saved to the User_ID. For that, i am trying to establish a hasOne relationship but i get a error for the following code can someone let me know what i am doing wrong? I am following the official documentation for this.
User model:
class users extends Model
{
protected $table = "users";
public function contacts()
{
return $this->hasOne('App\contacts','User_Id');
}
}
Contacts Model:
class contacts extends Model
{
public $table = "contacts";
public function Users(){
return $this->belongsTo('App\Users','User_id');
}
}
Controller:
public function eloquentget(){
$contacts = Users::find(1)->contacts->first();
return response()->json($contacts,200);
}
When i try this code in postman i get an Exception :
ErrorException
Trying to get property of non-object
What am i doing wrong? Any help will be appreciated.

Since you are saving multiple Contacts for any given User then you are using the wrong relation. You need to setup a One-Many relationship using hasMany().
class users extends Model
{
protected $table = "users";
public function contacts()
{
return $this->hasMany('App\contacts','User_Id','User_Id');
}
}

Try something like this
class users extends Model
{
protected $table = "users";
public function contacts()
{
return $this->hasMany('App\contacts','User_Id','User_Id');
}
}
And on your controller, You can use it like this
$contacts= User::find(1)->contacts; // it will return an array of collection

You don't need to use ->first(); because you already used relation hasOne
just use :
$contacts = Users::find(1)->contacts;
return response()->json($contacts,200);

Related

Laravel Eloquent - Get all records of child relation model

My data model is this:
Users > Offices > Organization
This is my model
class Organization extends Model {
protected $table = 'organizations';
public function offices()
{
return $this->hasMany('App\Models\Office');
}
public function users()
{
return $this->offices()->users();
}
....
So.. I want to get all users from an organization (of all the offices).
But I don't know how to do something like
$this->offices()->users();
(Avoiding user a manual collection or map to do that)
Thanks!
So, you have organization ID. You can load all users by using whereHas():
$users = User::whereHas('office', function ($q) use ($organizationId) {
$q->where('organization_id', $organizationId);
})
->get();
Make sure office() relationship is defined correctly in User model:
public function office()
{
return $this->belongsTo('App\Office');
}
Alternatively, you could define hasManyThrough() relationship:
public function users()
{
return $this->hasManyThrough('App\Office', 'App\User');
}
And use it:
$organization->users()

Laravel query multiple tables using eloquent

hi sorry bit of a newbie here but I am have three tables users, profiles, friends. they all have the user_id fields within them and I want fetch all of the fields in one statement using Eloquent and not DB::statement and doing the table joins.
How can I achieve this?
Try this
use the User class and the with method that laravel has to query model relationships
$user = User::with(['profile', 'friend'])->get();
Ensure your models has the correct relationships as follows:
app/models/User.php
public function friend () {
return $this->hasMany('Friend');
}
public function profile () {
return $this->hasOne('Profile');
}
app/models/Profile.php
public function user() {
return $this->belongsTo('User');
}
app/models/Friend.php
public function user() {
return $this->belongsTo('User');
}
use some thing like this:
You should define relations in your models with hasOne, hasMany.
class Review extends Eloquent {
public function relatedGallery()
{
$this->hasOne('Gallery', 'foreign_id', 'local_id');
}
}
class Gallery extends Eloquent {
public function relatedReviews()
{
$this->hasMany('Review', 'foreign_id', 'local_id');
}
}
$gallery = Gallery::with('relatedReviews')->find($id);
Will bring the object Gallery with
$gallery->id
gallery->name
...
$gallery->relatedReviews // array containing the related Review Objects

Cannot access Collection::$items

I've got some troubles with an eloquent query.
Users have many feeds and feeds have many items.
I need to get all the items that belongs to the feeds of the user order by date.
I've got a pivot table:
feed_user
----------
- id
- feed_id
- user_id
and relationships are defined like this in my models:
class UsersController extends BaseController {
public function feeds() {
return $this->hasMany('feed');
}
class Feed extends \Eloquent {
protected $fillable = [];
public function users() {
return $this->belongsToMany('User');
}
public function items() {
return $this->hasMany('Item');
}
class Item extends \Eloquent {
protected $fillable = [];
public function feed() {
return $this->belongsTo('Feed');
}
But when I do this query...
Auth::user()->feeds->items->orderBy('date', 'DESC')->get();
It returns this error:
Cannot access protected property Illuminate\Database\Eloquent\Collection::$items
There are a couple issues here.
First, the relationship on User model is not correct. A hasMany relationship is one half a one-to-many relationship. This would assume that a feed belongs to one user, and that the feed table has the user_id field. A many-to-many relationship is defined by adding a belongsToMany relationship on both models. So, a user belongsToMany feeds, and a feed belongsToMany users.
class User extends \Eloquent {
public function feeds() {
return $this->belongsToMany('feed');
}
}
Next, the error you're seeing is because Auth::user()->feeds returns a Illuminate\Database\Eloquent\Collection object. You're then trying to access the items attribute on the Collection, which is protected and throws the error you're seeing.
Finally, since Laravel does not use joins for relationships, you cannot order a query by a field on a related table without manually doing the join yourself.
Try using eager loading:
Auth::user()->with('feeds.items')->orderBy('date', 'DESC')->get();

Laravel Database Eloquent Relation queries for one model with multiple tables

I've defined a Model for multiple tables as seen here:
Laravel 4: can one model serve several DB tables?
I have many tables for the model Data:
data_2000
data_2001
...
And handle them in this model:
class Data extends \Eloquent {
public function __construct($year, array $attributes = array())
{
parent::__construct($attributes);
$this->table = 'data_' . $year;
}
public function country()
{
return $this->belongsTo('Country');
}
}
There's a One To Many relation with Country
class Country extends \Eloquent {
protected $table = 'countries';
public function data($year)
{
return $this->hasMany('Data('.$year.')');
}
public function region()
{
return $this->belongsTo('Region');
}
}
As I expected there's a missing argument if just return $this->hasMany('Data') so I tried $this->hasMany('Data('.$year.')') but of course it return an error of:
Class 'Data(2000)' not found
Is there a workaround to get all the Country->data from all the tables or just one table using eloquent's methods? Or should I just run multiple queries for all the years with a where('country_id', '=', $country->id)?
Thanks in advance, any ideas are appreciated.

In Laravel, how to set up a relationship for a "likes" table? Also, how to include that information in a query?

I have three tables: users, ideas, and ideas_likes. The ideas_likes table looks like:
ideas_likes
------------
id primary key
user_id foreign key
idea_id foreign key
liked boolean
There's already a one-to-many relationship set up between users and ideas. It looks something like this:
class User extends Ardent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $table = 'users';
public function ideas()
{
return $this->hasMany('Idea');
}
}
Similarly, the idea model looks like this:
class Idea extends Ardent {
protected $table = 'ideas';
public function user()
{
return $this->belongsTo('User');
}
}
My first question is: How do I create the IdeaLike model? And once that is finished, using Eloquent, how do I retrieve all liked ideas for a user?
===========================================================================
Lucasgeiter's updated solution worked great.
First, there's no need to create an IdeaLike model. You just need a many-to-many relationship
User
public function ideas(){
return $this->belongsToMany('Idea', 'ideas_likes')->withPivot('liked');
}
Idea
public function users(){
return $this->belongsToMany('User', 'ideas_likes')->withPivot('liked');
}
(By adding withPivot I tell Laravel that I want to have the liked column from the pivot table included in the result)
Usage
$user = User::find(1);
$likedIdeas = $user->ideas()->where('liked', true)->get();
By the way: You don't need to specify the $table if it is the plural of the model name.
Update
It looks like you actually really do need both, a one-to-many and a many-to-many relation.
So your final relations would look like this:
User
public function ideas(){
return $this->hasMany('Idea');
}
public function liked(){
return $this->belongsToMany('Idea', 'ideas_likes')->withPivot('liked');
}
Idea
public function likes(){
return $this->belongsToMany('User', 'ideas_likes')->withPivot('liked');
}
public function user(){
return $this->belongsTo('User');
}
(I just chose names for the relations that made kind of sense to me. You can obviously change them)
Usage
Liked ideas by a certain user: (id = 1)
$ideas = Idea::where('user_id', 1)->whereHas('likes', function($q){
$q->where('liked', true);
})->get();

Resources