how to transform sql query to laravel query - php

I'm a beginner so I'm still struggling with this.
I need your help to convert this query to Laravel's query
but apperently this one doen't work even in PhpMyAdmin.
SELECT `candidats.id`
FROM `candidats`,
`candidatures`
WHERE `candidats.id` = `candidatures.candidat_id`
ORDER By `candidatures.date_depot`;
What I want to do is to display all the candidates ordred by etat but this etat that belongs to candidatures table
In Candidat Model :
class Candidat extends Model
{
use HasFactory;
protected $table = 'candidats';
protected $fillable = [
'id_service',
'demande',
'nom',
'prenom',
'email',
'adresse',
'date_naissance',
];
public function candidatures()
{
return $this->hasMany(Candidature::class);
}}
In Candidature Model :
class Candidature extends Model
{
use HasFactory;
protected $table = 'candidatures';
protected $fillable = [
'candidat_id',
'date_depot',
];
public function candidat()
{
return $this->belongsTo(Candidat::class, 'candidat_id');
}
}
Thank you in advance.

Try to get like this
$Candidat = Candidat::with(['candidatures' => function ($query) {
$query->orderBy('date_depot', 'ASC');
}]);

well I've tried
$candidat = Candidat::join('candidatures','candidatures.candidat_id', '=', 'candidats.id')
->where('date_depot','=', $motcle)
->get();
and it works

Related

Conditionally append attribute to model in laravel

Is it possible to append an attribute to my model whenever a model scope is called?
For example in my controller I want to call a scope to append those dynamic attribute like :
$Media_query = OutDoorMedia::query();
$Media_query->orderby('created_at', 'desc');
$Media_query->PreviouslyOrdered();
$Media = $Media_query->get();
And in my model I want to do something like :
class OutDoorMedia extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'id',
'user_id',
'address',
'location',
'media_type',
];
}
class scopePreviouslyOrdered extends OutDoorMedia
{
public $appends = ['previously_ordered'];
public function getPreviouslyOrderedAttribute()
{
if ($this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id')->Where(function ($query) {
$query->where('status', MEDIA_ORDER_CHECKOUT_STATUS)
->orWhere('status', STATUS_TO_PAY);
})->exists()) {
return true;
} else {
return false;
}
}
}
But it's not working and I know it's wrong, How to achieve this?
I solved this problem with help of #apokryfos but with a bit tweak. hope this reduce wasting others time.
Instead of appending attributes on the model I have appended the said attribute to my model by the eloquent magic method :
$Media_query = OutDoorMedia::query();
$Media_query->orderby('created_at', 'desc');
$Media = $Media_query->get()->each(function ($items) {
$items->append('previously_ordered');//add this attribute to all records which has the condition
});
In Model As apokryfos said I have put these two methods:
public function PreviousOrders() {
return $this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id');
}
public function getPreviouslyOrderedAttribute() {
return $this->PreviousOrders()->exists();
}
But I don't need this method and I had to remove it from the model because if it exist in model it will automatically append to model:
public $appends = [ 'previously_ordered' ];
I think there's a misunderstanding on how scopes should work. A scope is basically like a shortcut query for a model. You are using it to test existance of a relationship but there's a better way to do that using whereHas
Here's how you would achieve this using a relationship:
class OutDoorMedia extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'id',
'user_id',
'address',
'location',
'media_type',
];
public function previousOrders() {
return $this->hasMany('App\Models\OutDoorMediaOrders', 'odm_id', 'id');
}
public function getPreviouslyOrderedAttribute() {
return $this->previousOrders()->exists();
}
}
Then you simply do:
$Media_query = OutDoorMedia::whereHas('previousOrders')
->orderby('created_at', 'desc');
If you what the dynamic attribute appended on the model automatically you can just add the following to the model:
public $appends = [ 'previously_ordered' ];
I guess if you want the best from both worlds you can do:
class OutdoorMediaWithPreviouslyOrdered extends OutDoorMedia {
public $appends = [ 'previously_ordered' ];
}
Then when you need the appending model you can use :
$Media_query = OutdoorMediaWithPreviouslyOrdered ::orderby('created_at', 'desc');

Show data from 2 tables in laravel 5.4

I have a simple code, and now I want to select data from 2 tables. Then I want to show in my view. Here's my code
model:
Tikpro.php
class Tikpro extends Model {
public $table = "TIKPRO";
public $primaryKey = "ID_TIKPRO";
public function permintaan() {
return $this->hasMany('Permintaan', 'TIKPRO_ID', 'ID_TIKPRO');
}
model:
Permintaan.php
class Permintaan extends Model {
public $table = "PERMINTAAN";
public $fillable = array(
'NOMOR_TICKET',
'TGL_PERMINTAAN',
'NAMA_REQUESTER',
'BARANG_PERMINTAAN',
'NO_FPBJ',
'TGL_INPUT_FPBJ',
'TARGET_SELESAI',
'KETERANGAN',
'TINDAK_LANJUT_AKHIR',
'STATUS',
'FPB',
'RFQ',
'DO',
'BAST',
'TGL_DEADLINE',
'titik_proses',
'TIKPRO_ID',
);
public $primaryKey = "ID_PERMINTAAN";
public function tikpro() {
return $this->belongsTo('Tikpro','TIKPRO_ID','ID_TIKPRO');
}
Controller:
PermintaanController.php
public function details($ID_PERMINTAAN) {
$query = DB::table('PERMINTAAN')->select('TIKPRO.NAMA_TIKPRO')->join('TIKPRO','TIKPRO.ID_TIKPRO','=','PERMINTAAN.TIKPRO_ID')->get('all');
$jebret = Permintaan::find($ID_PERMINTAAN);
return view('permintaan.details', compact('jebret'))->with($query);
}
And how can I show it? In my view I try {{ $jebret->$query }} . But still can't show the data.
How should I write code? Thanks
I think you can try this
public function details($ID_PERMINTAAN) {
$query = DB::table('PERMINTAAN')->select('TIKPRO.NAMA_TIKPRO')->join('TIKPRO','TIKPRO.ID_TIKPRO','=','PERMINTAAN.TIKPRO_ID')->where('PERMINTAAN.ID_PERMINTAAN',$ID_PERMINTAAN)->get();
return view('permintaan.details', compact('query'));
}
Hope this work for you
There's 2 ways here. The first and easiest (if you've set it up correctly) is the relationship. https://laravel.com/docs/5.4/eloquent-relationships. To use the one in your example you want to do this:
$permintaans = Permintaan::query()->get()->all();
return view('permintaan.details', [
'permintaans' => $permintaans,
]);
//In the view
#foreach($permintaans as $permintaan)
<tr>{{$permintaan->tikpro->attribute}}</tr>
#endforeach
Another way like you've attempted is the join. In the select though I would leave it blank so you get all columns!
$permintaans = Permintaan::query()
->join('TIKPRO','TIKPRO.ID_TIKPRO','=','PERMINTAAN.TIKPRO_ID')
->get()
->all();

Laravel 5.2 Model Relationships

im new to Laravel and have a relationship question.
The goal is to get all News where news.page_id = page.id AND page.pagetype_id = pagetype.id WHERE pagetype.component = news AND page.app_id = 1
class News extends Model
{
protected $table = 'news';
protected $fillable = ['page_id', 'title', 'description', 'active', 'created_at', 'updated_at'];
}
class Page extends Model
{
protected $table = 'pages';
protected $fillable = ['app_id', 'unique_id', 'pagetype_id', 'title', 'picture_url', 'short_description', 'description', 'valid_since', 'valid_until', 'extras', 'active', 'created_at', 'updated_at'];
public function pagetype() {
return $this->belongsTo('App\Models\PageType', 'pagetype_id');
}
}
class PageType extends Model
{
protected $table = 'pagetypes';
protected $fillable = ['pagetype', 'component', 'active', 'created_at', 'updated_at'];
public function page() {
return $this->belongsToMany('App\Models\Page', 'pagetypes', 'id', 'id');
}
}
// now i need All News Items where page.pagetype_id = pagetypes.id and patchtypes.component = news
// First Attempts are
Page::whereHas('pagetype', function ($q) {
$q->where('component', 'news');
})->where(['app_id' => 1])->get();
// result is all Pages which has the proper component news.
This is what i have tried yet, but in my attempt i'll only receive the proper pages but of course not the news.
My "current" solution is to get all the pages and then loop through News::where('page_id', $myPageId). But im pretty sure its possible to get a proper relationship to get also news.
I cant do any other model since there are many different pagetypes and components aswell.
Thanks so far.
You need to add relationship function to news model.
public function pages() {
return $this->belongsTo('App\Models\Page');
}
And call it through News model.
News::with('pages')->where('app_id',1);
First off all I think that you are wrong with you PageType relation
class PageType extends Model
{
protected $table = 'pagetypes';
protected $fillable = ['pagetype', 'component', 'active', 'created_at', 'updated_at'];
public function page() {
return $this->hasMany('App\Models\Page');
// if i understood you correctly you haven't got any pivot table
}
}
Then you should link your News and Page like so
News.php
class News extends Model
{
protected $table = 'news';
protected $fillable = ['page_id', 'title', 'description', 'active', 'created_at', 'updated_at'];
public function page() {
return $this->belongsTo('App\Models\Page');
}
}
Page.php
class Page extends Model
{
protected $table = 'pages';
protected $fillable = ['app_id', 'unique_id', 'pagetype_id', 'title', 'picture_url', 'short_description', 'description', 'valid_since', 'valid_until', 'extras', 'active', 'created_at', 'updated_at'];
public function pagetype() {
return $this->belongsTo('App\Models\PageType');
}
public function news() {
return $this->hasMany('App\Models\News');
}
}
Then you can achieve your goal
News::whereHas('page', function($q) use($appId) {
$q->where('app_id',$appId);
})->whereHas('page.pagetype', function($q) {
$q->where('component', 'news');
})->get();

How do I get the user-name in every thread (Laravel)?

I wan't to get the name of the user who created is own thread. Like Michael did a thread about food. So at the bottom of the food-thread should be the name of Michael.
I've wrote the code for this but it doesn't really works. Maybe someone of you can find the mistake.
I have two models. A thread Model and a users model.
thread model:
<?php
namespace App\Models\Thread;
use Illuminate\Database\Eloquent\Model;
use App\User;
class Thread extends Model {
public $table = 'thread';
public $fillable = [
'thread',
'content',
'user_id'
];
public function userthread() {
return $this->belongsTo('User','user_id', 'id');
user model:
<?php
namespace App;
use ...
protected $table = 'users';
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
public function threaduser() {
return $this->hasMany('App\Models\Thread\Thread','user_id', 'id');
}
}
and now the controller method, where I'm trying to get the name:
public function show($id)
{
$thread = Thread::query()->findOrFail($id);
$threaduser = Thread::where('user_id', Auth::user()->id)->with('userthread')->get();
return view('test.show', [
'thread' => $thread,
'threaduser' => $threaduser
]);
}
in my html:
{{$threaduser->name}}
The error message I get is :
Undefined property: Illuminate\Database\Eloquent\Collection::$name (View: /var/www/laravel/logs/resources/views/test/show.blade.php)
I hope someone can help me there.
change it to
{{$threaduser->userthread->name}}
change userthread() function in your Thread Class to
public function userthread() {
return $this->belongsTo('App\User','user_id', 'id');
}
get() gives you a Collection not a Model you either have to do a foreach on it like
#foreach ($threadusers as $threaduser)
{{ $threaduser->userthread->name }}
#endforeach
Or use first instead of get if there is only one Thread per User.
Depending on what you want to do, of course.

How to use the `where` method along with the `with` method in laravel 4?

Given the following, very simple, example:
Country Class
class Country extends Eloquent {
protected $table = "countries";
protected $fillable = array(
'id',
'name'
);
public function state() {
return $this->hasMany('State', 'country_id');
}
}
State Class
class State extends Eloquent {
protected $table = "states";
protected $fillable = array(
'id',
'name',
'country_id' #foreign
);
public function country() {
return $this->belongsTo('Country', 'country_id');
}
}
How can I list all the states, based on the id or the name of the country.
Example:
State::with('country')->where('country.id', '=', 1)->get()
The above returns an area, as country is not part of the query (Eloquent must attach the join later, after the where clause).
I think you're either misunderstanding the relations or over-complicating this.
class Country extends Eloquent {
public function states() {
return $this->hasMany('State', 'state_id');
}
}
$country = Country::find(1);
$states = $country->states()->get();

Categories