Laravel relation one to many get results joined - laravel

I'm kinda lost one this one, I really can't find the problem, I have been watching a lot of questions all over the web but still can't seem to put this working properly.
I have two tables, the tabelaAngaricao table and the tabelaFotos table with a relationship of one-to-many, meaning that a tabelaAngariacao can have many tabelaFotos, and tabelaFotos as a angariacaoid(foreign key) so my tabelaAngariacao model is:
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\TabelaFotos;
class TabelaAngariacao extends Model
{
protected $table = 'tabelaAngariacao';
public function TabelaFotos()
{
return $this->hasMany(TabelaFotos::class, 'angariacaoid');
}
}
and my tabelaFotos model is:
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\TabelaAngariacao;
class TabelaFotos extends Model
{
protected $table = 'tabelaFotos';
public function TabelaAngariacao()
{
return $this->belongsTo('App\TabelaAngariacao');
}
}
What I want is to get all results joined by the angariacaoid, so in my controller I have:
public function index()
{
$results = DB::table('tabelaAngariacao')
->leftJoin('tabelaFotos', 'tabelaAngariacao.id', '=', 'tabelaFotos.angariacaoid')
->select('tabelaAngariacao.*')
->get();
}
Could someone help me on finding the problem? What is that I'm doing wrong?

You don't need to add select. Try following
$results = DB::table('tabelaAngariacao')
->leftJoin('tabelaFotos', 'tabelaAngariacao.id', '=', 'tabelaFotos.angariacaoid')
->get();
The above script will give you columns from both tables.

And probably you don't need to use DB::table, you can use Eloquent Queries instead, since you've defined your relationsips
You can try it by doing this.
$results = TabelaFotos::with('TabelaAngariacao')->get();
Here is how it works
$results = ModelName::with('relationship_in_model_name')->get();
Hope it works

Related

Property does not exist in collection while using belongsToMany in laravel eloquent

I am using Laravel 8.X and eloquent to develop a web app.
I have a pivot table 'portal_event_users'
I am trying to add a belongsToMany relationship to the portal_users in the model of portal_event_users table.
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class EventUser extends Model
{
use HasFactory;
protected $table = 'portal_event_users';
public function users()
{
return $this->belongsToMany(User::class);
}
public function events()
{
return $this->belongsToMany(Event::class);
}
}
I have the following statements in the controller
$eventusersobj = \App\Models\EventUser::select('*')
->where('event_id', '=', $event_id)
->get();
$response = $eventusersobj->users->keyBy('id');
It is returning the following error
Property [users] does not exist on this collection instance.
Can someone please advice on how can i change this error?
Thanks in advance
As it returns a collection, you can use pluck()
$eventusersobj->pluck('users')->each(function($user){
$user->keyBy('id');
})

How to convert sql query to eloquent in laravel

how to convert sql to eoquent
$getAllRequirementRecord = Requirement::select()
->join('requirement_locations','requirements.id','=','requirement_locations.requirement_id')
->join('locations','requirement_locations.location_id','=','locations.id')
->where('isdelete',2)
->where('requirements.id',$id)->get();
help to solve this problems
Let's say we've an eloquent Model named Requirement and we've a database table named requirements associated with that model and we have another model named requirementLocation associated with a database table named requirement_locations.
and we have a database relation ship between both tables "requirements" & "requirement_locations" based on the requirement_id
Requirement Model:
class Requirement extends Model{
protected $table = 'requirements';
}
RequirementLocation Model:
class RequirementLocation extends Model{
protected $table = 'requirement_locations';
}
and Now we need to setup a relationship between these two models like the database tables .. so inside the Requirement we're gonna use has many relationship
use App\RequirementLocation;
class Requirement extends Model{
protected $table = 'requirements';
public function locations(){
return $this->hasMany(RequirementLocation::class);
}
}
and simply to fetch your data use
$id = 1;
$getAllRequirementRecord = Requirement->whereHas('locations' , function($query){
$query->where('isdelete',2);
})->where('id',$id)->with('locations')->get();
You can use eloquent with SQL raw query likewise:
$activeusers = User::selectRaw('users.name, count(*) submitted_games')
->join('games', 'games.user_id', '=', 'users.id')
->groupBy('users.name')
->orderBy('submitted_games', 'DESC')
->get();
To output to the screen the last queries ran you can use this :
dd(DB::getQueryLog());
I hope you have created Requirement, Location and RequirementLocation models
So first add this code in Requirement.php model file:
public function locations()
{
return $this->hasMany('RequirementLocation', 'requirement_locations');
}
Then access the requirements like this :
$requirement = Requirement::where('id', $requirement_id)->first();
Now you can access locations like this :
$requirement->locations;

Most Recent Updates in Laravel

I have a list of books in my database and each book have chapters. my models are
Books.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
protected $guarded = [];
public function chapters()
{
return $this->hasMany(Chapter::class);
}
}
Chapter.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Chapter extends Model
{
protected $guarded = [];
public function book()
{
return $this->belongsTo(Book::class);
}
}
How can make a page that will show the books in order manner from latest to old?
Also, the order is based on the chapter being updated or added in a book. If one of the old books is being updated by adding 1 more chapter, that book will show first on the most recent updated books.
Thank you!
I am using Laravel 5.6 and Vue JS
Option 1:
You should use joins in query:
$books = Books::select('books.*')
->leftJoin('chapters', 'chapters.book_id', '=', 'books.id')
->groupBy('books.id')
->orderByDesc('chapters.updated_at')
->get();
Option 2:
If you don't need paginate and want to show all books in one page, you can try to sort a collection by relation value.
Add latestChapter relation:
public function latestChapter()
{
return $this->hasOne(Chapter::class)->orderByDesc('updated_at');
}
Get and sort:
$books = Books::with('latestChapter')->get();
$books = $books->sortByDesc(function($item){
return $item->latestChapter ? $item->latestChapter->updated_at : '1970-01-01';
});

Laravel - Getting first thread per forum all() result

I'm learning VueJS and trying to develop a forum system
I am trying to get the latest post from the threads relationship per forum in my forum model.
This is my Forum Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Forum extends Model
{
public $table = 'forums';
public $timestamps = false;
public function threads() {
return $this->hasMany('App\Thread')->orderBy('id', 'DESC');
}
public function getFirstThread() {
return $this->threads()->first();
}
}
So I thought maybe this would work but it didn't
Forum::with('getFirstThread')->get();
Any idea's how I can achieve this without having to loop through everything and getting first thread for every result?
TLDR: Trying to get the latest Thread per Forum without having to loop through all forums.
You can $append the method results by using getMethodNameAttribute()
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Forum extends Model
{
public $table = 'forums';
public $timestamps = false;
protected $appends = ['firstthread'];
public function threads() {
return $this->hasMany('App\Thread')->orderBy('id', 'DESC');
}
public function getFirstThreadAttribute() {
return $this->threads()->first();
}
}
You could define another mapping as hasOne in your model to get latest thread per forum, Call latest('id') on your mapping and pass id as a column to sort
public function latest_threads() {
return $this->hasOne('App\Thread')->latest('id');
}
Then you can easily eager load your relationship as
Forum::with('latest_threads')->get();

laravel - how to give alias name to eloquent model

<?php
namespace App\Http\Models;
use Illuminate\Database\Eloquent\Model;
use Sofa\Eloquence\Eloquence;
use Sofa\Eloquence\Mappable;
class User extends Model
{
use Eloquence, Mappable;
public $id;
public $name
}
$data= User::select('distinct User.name')->join('Member as m','User.id','m.userId')->whereRaw('User.name is not null')->get();
I want to avoid Using table name all time instead i want to use alias name.
You can use the Model::from method for this
<?php
class User extends Model
{
use Eloquence, Mappable;
public $id;
public $name
}
$data= User::from('User as u')
->select('distinct u.name')
->join('Member as m','u.id','m.userId')
->whereRaw('u.name is not null')
->get();
NOTE: I see a lot upvotes, but this approach isn't good practice. It's better to find a different approach. My advice stay on the common walked paths.
You can add
protected $table = 'users as u';
-- users is exact your table name in db
And use it like this
User::where('u.id', 1229)->select('u.email')->get();
This works for me:
$query = Model::from('table as alias')->get();
And u can check it with:
dd($query->toSql());

Resources