Laravel Collection is empty - php

I am trying to learn more about Laravel ORM and ORM in general,
but I have problems I can't solve by myself.
This is my users table:
And here is my Article table:
My User eloquent model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'users';
public function article()
{
return $this->hasMany('\App\Models\Article', 'autor_id');
}
}
And my Article eloquent model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'clanky';
public function autor() {
return $this->belongsTo('\App\Models\User', 'id');
}
}
I am trying to access each article with its author data using this code:
$articles = Models\Article::all();
foreach($articles as $art)
{
echo $art->autor->name . "<br>";
}
The problem is the model is returning only userdata from first article, not the second and so on.
Any thoughts on what could cause this? Thanks in advance.

I think you need to update your code like.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'Article';
public function autor() {
return $this->belongsTo('\App\Models\User', 'autor_id', 'id');
}
}
$articles = Models\Article::with('autor')->get();
foreach($articles as $art)
{
echo $art->autor->name . "<br>";
}

Related

Add Pagination to relationship and get the relationship's relationship - Laravel

I am building a forum website using Laravel and Vue.
I have three tables: forums, posts, and users.
One forum can have multiple posts, each post has a user who created the post.
When the user clicks on one forum, I want to display the latest 10 posts to this forum with the paginate method.
Forum.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Forum extends Model {
use HasFactory;
protected $table = 'forums';
protected $guarded = [];
/**
* Get the forum posts
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function posts() {
return $this->hasMany(Post::class)->orderBy('created_at', 'DESC');
}
}
Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
use HasFactory;
protected $table = 'posts';
protected $guarded = [];
/**
* Get the post's user
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user() {
return $this->belongsTo(User::class);
}
}
User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable {
use HasFactory, Notifiable;
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Get the user posts
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function posts() {
return $this->hasMany(Post::class);
}
}
Here I retrieve the forum posts with the users.
ForumService.php
<?php
namespace App\Services;
use App\Models\Forum;
class ForumService {
public static function getForumPosts($forumId) {
$forum = Forum::with('posts.user')->find($forumId);
dd($forum);
}
}
However, I want to retrieve only 10 posts and get each post's user, so how do I do that in a relationship? The posts are paginated, but how to I get now the posting user? Because the dot syntax is applying to the user, therefore I paginate the user, not the posts.
ForumService.php
<?php
namespace App\Services;
use App\Models\Forum;
class ForumService {
public static function getForumPosts($forumId) {
$forum = Forum::with(
[
'posts' => function ($query) { // How do I get the post user?
return $query->paginate(10);
}
]
)->find($forumId);
dd($forum);
}
}
Just add the with method inside the query scope of the function you have created.
$forum = Forum::with(
[
'posts' => function ($query) {
// returns posts with user
return $query->with('user')->paginate(10);
}
]
)->find($forumId);
Now you can access the first user with $forum->posts[0]->user which will not query to the database but will prefetch the users and populate it in paginator collection.
As you have already the id of the forum you can only retrieve posts which belongs to that Forum and paginate them like this
public static function getForumPosts($forumId) {
return Forum::find($forumId)->posts()->paginate(10);
}
If you want to eager load Post creator you can perform that like this
public static function getForumPosts($forumId) {
return Forum::find($forumId)->posts()->with(['user'])->paginate(10);
}

Laravel Eloquent filter not found

I am trying to create a filter in Laravel.
I want to filter on the database field transmission but it is not working.
Here is my Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Occasion extends Model
{
protected $table = 'hexon_occasions';
public $primaryKey = 'id';
public $timestamps = true;
}
My Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use EloquentBuilder;
use App\Occasion;
class OccasionController extends Controller
{
public function index(Request $request)
{
$occasions = EloquentBuilder::to(
Occasion::class,
$request->all()
);
return $occasions->get();
}
public function show($slug)
{
$occasions = Occasion::where('slug', $slug)->first();
return view('occasions.show')->with('occasions', $occasions);
}
}
The filter:
namespace App\EloquentFilters\Occasion;
use Fouladgar\EloquentBuilder\Support\Foundation\Contracts\Filter;
use Illuminate\Database\Eloquent\Builder;
class TransmissionFilter implements Filter
{
/**
* Apply the age condition to the query.
*
* #param Builder $builder
* #param mixed $value
*
* #return Builder
*/
public function apply(Builder $builder, $value): Builder
{
return $builder->where('transmission', $value);
}
}
And the URL i am using is: https://www.laravel.bvdodev.nl/occasions?filter[transmission]=H
But I am getting the error: Not found the filter: FilterFilter
Does someone know what I am doing wrong?
Thanks for your time!

Get model with hasMany is not working in Laravel

I try to print on my view all the atleti associated with a squadra x but the method $squadra->atleti() always returns me ant empty array.
Have you got some ideas to get this working?
Down below you can find my code and my db structure.
Squadra is team in english. One team can be associated to many atleti (it stands for players).
I think there is some problems with the foreign key.
Thank you for your help.
<?php
//Squadra Model
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Squadra extends Model
{
protected $connection = 'custom_mysql';
protected $table = 'squadra';
/**
* Get the Allenatore for the Squadra.
*/
public function allenatore()
{
return $this->belongsTo('App\Models\Allenatore');
}
/**
* Get the Atleta for the Squadra.
*/
public function atleti()
{
return $this->hasMany('App\Models\Atleta');
}
}
<?php
//Atleta Model
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Atleta extends Model
{
protected $table = 'atleta';
protected $connection = 'custom_mysql';
/**
* Get the Atleta for the Squadra.
*/
public function squadra() {
return $this->belongsTo( 'App\Models\Squadra' );
}
}
<?php
//Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
class AtletaController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function getSquadra($id)
{
$squadra = Squadra::find($id);
return view('custom.squadra.dettaglio', compact('squadra'));
}
//View
#foreach( $squadra->atleti() as $atleta )
<tr class="success">
<td>{{ $atleta->id }}</td>
<td>{{ $atleta->nome}}</td>
<td>{{ $atleta->cognome}}</td>
</tr>
#endforeach
Here it is the output of dd($squadra)
Your are sending the atleti to the view, instead of the squadra. Try to change your controller function to this:
public function index()
{
$squadra = Squadra::firstOrFail(); // You need a paremeter in a route that defines which squadra to show. This will show the first one.
return view('custom.atleta.index', compact('squadra'));
}

how to join two models in laravel 5.2

I have two models as Project and Collaborator this is My tables
Project column
id
project_name
project_note
user_id
Collaborator Model
id
project_id
collaborator_id
I need join this models to get project_name instead project_id of Collaborator Model.
how can I do this. I read www.laravel.com documents but difficult to understand. help me in code...
project Model
<?php
namespace App;
use Auth;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
/*
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['project_name', 'project_notes', 'project_status', 'due_date'];
public function scopePersonal($query)
{
return $query->where('user_id', Auth::user()->id);
}
//
}
collaborator Model
<?php
namespace App;
use Auth;
use Illuminate\Database\Eloquent\Model;
class Collaboration extends Model
{
protected $table = 'project_collaborator';
/*
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['project_id', 'collaborator_id'];
/*
* Get the user that is a collaborator on another project
* #return collection
*/
public function user()
{
return $this->belongsTo(User::class, 'collaborator_id');
}
/*
* Query scope to return information about the current project
* #param $query
* #param int $id
* #return query
*/
public function scopeProject($query, $id)
{
return $query->where('project_id', $id);
}
public function scopeColabo($query)
{
return $query->where('collaborator_id',Auth::user()->id);
}
}
Based on your comment, you need to add a relationship hasOne to your collaboration model:
class Collaboration extends Model
{
.....
public function project()
{
return $this->hasOne('App\Project');
}
.....
}
The method project() will define your relationship with your project model. And then you'll be able to get the collaboration project name like this:
$collaborations = Collaboration::with('project')->get();
foreach ( $collaborations as $collaboration ) {
echo $collaboration->project->project_name;
}
You can read more in the documentation.
In your Collaboration class add the followoing relation:
public function project()
{
return $this->belongsTo('App\Project');
}
And in your User class define a relation as:
public function collaborations()
{
return $this->hasMany('App\Collaboration', 'collaborator_id');
}
Then you can get all the collaborations of logged in user by:
$collaborations = auth()->user()->collaborations()->with('project')->get()
or
To get all collaborations you can so as:
$collaborations = Collaboration::with('project')->get();
In your view file:
#foreach ($collaborations as $collaboration)
{{ $collaboration->project->project_name }}
#endforeach

Laravel: Trying to get relationship

User:
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
public function email_preferences()
{
return $this->hasOne('EmailPreference');
}
}
EmailPreference:
class EmailPreference extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'email_preferences';
public function user()
{
return $this->belongsTo('User');
}
}
users table
id PK
first_name
last_name
email
email_preferences table
id PK
user_id FK (users.id)
newsletter
I'm trying to display the email preferences for a user:
$user = Auth::user();
echo '<pre>';
print_r($user->email_preferences);
exit;
I get nothing...
It sounds like you want something like this:
<?php
$user = Auth::user();
echo 'Receive newsletter? ' . ($user->emailPreferences->newsletter ? 'Yes' : 'No');
EDIT:
I did some digging & found that underscores can be tricky when used in Eloquent function/property names. If you eliminate the underscore, things should just work:
<?php
class User extends Eloquent implements UserInterface, RemindableInterface {
public function emailPreferences()
{
return $this->hasOne('EmailPreference');
}
}
See this answer: Laravel 4 Eloquent ORM accessing one-to-one relationship through dynamic properties

Categories