how to make JOINTURE(join) in laravel - php

I have two table SALARIES and POINTAGES And between them a relationship hasMany belongsTo, I want to display for each POINTAGE a SALARIES corresponds but it gives me empty datatable.
consulter.blade.php
#foreach($pointages as $pointage)
<tr>
<td>{{ $pointage->datep }}</td>
<td>{{ $pointage->chantier }}</td>
<td>{{ $pointage->ouvrage }}</td>
<td>{{ $pointage->nbrj }}</td>
<td>{{ $pointage->solde }}</td>
<td>{{ $pointage->salarie->nom }}</td>
</tr>
#endforeach
Pointage.php
protected $fillable = [
'salarie_id', 'datep', 'solde', 'nbrj' , 'ouvrage' , 'chantier' , 'prime' ,
];
public function salarie(){
return $this->belongsTo('App\Salarie');
}
Salarie.php
public function pointages(){
return $this->hasMany('App\Pointage');
}
pointages migration:
public function up(){
Schema::table('pointages', function (Blueprint $table) {
$table->integer('salarie_id')->unsigned()->after('id');
$table->foreign('salarie_id')->references('id')->on('salaries');
});
}
SalarieController.php
public function consulter()
{
$salaries = Salarie::with('pointages')->get();
$pointages = Pointage::with(["salaries"])->has("salarie")->get();
return view('salarie.consulter', compact('salaries','pointages'));
}

You need to define explicit the relationship functions:
// app\Salarie.php
class Salarie extends Model
{
protected $fillable = ['nome'];
public function pointages(){
return $this->hasMany('App\Pointage','salarie_id','id');
}
}
// app\Pointage.php
class Pointage extends Model
{
protected $fillable = [
'salarie_id', 'datep', 'solde', 'nbrj' , 'ouvrage' , 'chantier' , 'prime' ,
];
public function salarie(){
return $this->belongsTo('App\Salarie');
}
}
And use like below to consulter all of pointages relate with salaries table:
// app\Http\Controllers\SalarieController.php
class SalarieController extends Controller
{
public function consulter()
{
// test your model with this simple query
// $salaries = Salarie::find(1);
// $pointages = $salaries->pointages()->get();
// return view('salarie.consulter', compact('pointages'));
// if the upon test runs well, the follow codes will work
$salaries_ids = Salarie::with('pointages')->pluck('id');
$pointages = Pointage::whereHas('salarie', function($query) use ($salaries_ids) {
$query->whereIn('salarie_id', $salaries_ids);
})->get();
return view('salarie.consulter', compact('pointages'));
}
}
Hope this helps, ask me if you need!

Some things you could try:
I'm not sure if it matters but you could try removing the brackets in de with() like so Pointage::with("salaries")->has("salarie")->get();
Another thing you should check if the primary and foreign keys of Salarie and Pointage are correct. Laravel documentation states the following:
In the example above, Eloquent will try to match the user_id from the Phone model to an id on the User model. Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with _id. However, if the foreign key on the Phone model is not user_id, you may pass a custom key name as the second argument to the belongsTo method.

Related

Undefined property: stdClass::$salarie

I have two table SALARIES and POINTAGES And between them a relationship hasMany belongsTo, I want to display for each POINTAGE a SALARIES corresponds but it gives me this error:
Undefined property: stdClass::$salarie
consulter.blade.php
#foreach($pointages as $pointage)
<tr>
<td>{{ $pointage->datep }}</td>
<td>{{ $pointage->chantier }}</td>
<td>{{ $pointage->ouvrage }}</td>
<td>{{ $pointage->nbrj }}</td>
<td>{{ $pointage->solde }}</td>
<td>{{ $pointage->salarie->nom }}</td>
</tr>
#endforeach
Pointage.php
protected $fillable = [
'salarie_id', 'datep', 'solde', 'nbrj' , 'ouvrage' , 'chantier' , 'prime' ,
];
public function salarie(){
return $this->belongsTo('App\Salarie');
}
Salarie.php
public function pointages(){
return $this->hasMany('App\Pointage');
}
pointages migration:
public function up(){
Schema::table('pointages', function (Blueprint $table) {
$table->integer('salarie_id')->unsigned()->after('id');
$table->foreign('salarie_id')->references('id')->on('salaries');
});
}
SalarieController.php
public function consulter(){
$salaries = Salarie::with('pointages')->get();
$pointages = DB::table('pointages')->get();
return view('salarie.consulter', compact('salaries','pointages'));
}
If you want to use a relationship, like public function salarie() on your Pointage model, you need to actually query it. Don't use DB::table(), use Pointage:
$pointages = Pointages::get();
Also, to avoid additional queries when looping $pointages, eager load your relationship:
$pointages = Pointages::with(["salarie"])->get();
In summary, DB::table() does not return a Pointage model, so you can't use ->salarie. Use your model.
Edit: There is a chance that a Pointage doesn't have a Salarie associated, so you need to handle that. Either enforce the relationship with a ->has() query, or check while looping:
$pointages = Pointages::with(["salarie"])->has("salarie")->get();
Or, in your view:
#if($pointages->salarie)
<td>{{ $pointage->salarie->nom }}</td>
#else
<td>No Salarie...</td>
#endif

display data name instead of id property

I can't get the name property to display in my index always showing error
"Function name must be a string"
Controller
public function index()
{
$accounts = Account::with('student')->get();
return $accounts('Student_id');
$student = Student::find($id, ['id', 'studentname']);
return view('accounts.index',compact('accounts'));
}
Model
protected $fillable = [
'accountname',
'Student_id',
];
public function student() {
return $this->belongsTo(Student::class);
}
View Code:
<tbody>
#foreach ($accounts as $account)
<tr>
<td>{{ $account->accountname }}</td>
<td> {{$account->student->studentname}}</td>
</tr>
#endforeach
</tbody>
I'm trying to display the studentname instead of Student_id using one to many relationship.
this is the Error
Note: but if i changed this {{$account->student->studentname}} to this {{$account->Student_id}} it work but only showing the id not the name.
Remove these lines:
return $accounts('Student_id');
$student = Student::find($id, ['id', 'studentname']);
Also, since you're not using a standard foreign key name, you need to add it to the definition:
public function student()
{
return $this->belongsTo(Student::class, 'Student_id');
}
Also, it's a good idea to follow Laravel naming conventions which you will find in my repo and rename Student_id to student_id. In this case, your relationship will work without defining a foreign key.
Update
The solution for the third issue you have is:
<td> {{ optional($account->student)->studentname}}</td>

Inner join using eloquent in Laravel 5.1

I have a doubt that I couldn't find an answer anywhere.
I'm new to eloquent and to make the basic stuff it is excelent!
Now I need to query data from different tables and I was wondering if I can do it with eloquent.
I have two models:
class Worker extends Model {
protected $table = 'workers';
public $timestamps = true;
public function area()
{
return $this->belongsTo('Area');
}
}
And this one
class Area extends Model {
protected $table = 'areas';
public $timestamps = true;
public function worker()
{
return $this->hasMany('Worker');
}
}
So basically a worker belongs to an area and an area has many workers.
Now I want to show in a table the name of the worker and the name of the area that he belongs to.
I can do it using the query builder but I wanted to know if I can do it with eloquent.
I saw a post in laracast with this code:
$workers = Worker::with('area')->get();
Now when I use that I get the following error:
Class 'Area' not found
I don't know why I get that error when the function 'area' exists in the Worker class and in the WorkerController I'm using
use App\Area;
What I want to be able to do is the following:
#foreach ($workers as $worker)
<td>{{ $worker->name }}</td>
<td>{{ $worker->lastname }}</td>
<td>{{ $worker->areas->name }}</td>
#endforeach
Like I said, I already I'm able to accompish this using laravel's query builder but I just want to know if I can make more use of the Eloquent :)
Thank you for your time.
Just in case anyone asks here is my raw query:
$workers = DB::table('workers')
->join('areas', 'areas.id', '=', 'workers.area_id')
->select('workers.*', 'areas.name as area')
->get();
That's the one I'm using and it works perfectly fine, thank you! :)
You are missing namespaces in your relations.
public function area()
{
return $this->belongsTo('App\Area');
}
and
public function worker()
{
return $this->hasMany('App\Worker');
}
You need to use function like you named in model "area" not "areas":
#foreach ($workers as $worker)
<td>{{ $worker->name }}</td>
<td>{{ $worker->lastname }}</td>
<td>{{ $worker->area->name }}</td>
#endforeach

Why do i need first() in blade view with one to many relationship?

I have two tables
One QUESTIONS_TITLES entry has many QUESTIONS entries. The titles contain a group of questions.
QUESTIONS
id | question | ... | question_titles_id
QUESTIONS_TITLES
id | title
MODEL QUESTION
class Question extends \Eloquent {
public function questionTitle() {
return $this->belongsTo('QuestionsTitle', 'question_titles_id');
}
}
MODEL QUESTION
class QuestionsTitle extends \Eloquent {
protected $fillable = ['title', 'question_cat_id', 'type'];
protected $table = 'questions_titles';
public function question() {
return $this->hasMany('Question');
}
}
in my question controller i do:
$questions = Question::all();
$this->layout->content = View::make('questions.index', compact('questions'));
in my view i want a group of questions with the corresponding parent title
#foreach ($questions as $question)
<tr>
<td>{{ $question->questionTitle()->first()->title }}</td>
<td>{{ $question->id }}</td>
<td>{{ $question->question }}</td>
</tr>
#endforeach
this works. but why do i need first()? it doesn't look clean
when i drop it i get
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$title (View: /vagrant/app/views/questions/index.blade.php)
$question->questionTitle() returns a BelongsTo object, not the QuestionTitle object. When you call $question->questionTitle()->first() you're executing the first() method on the relationship. This through laravel magic is getting you the correct answer. Though what you should really be doing is: $question->questionTitle->title. When you access the questionTitle attribute Laravel automatically resolves the relationship for you.

Laravel eloquent - One to many relationships (Trying to get property of non-object)

I have "posts" table that has many-to-one relationship with "categories" table. The goal is to show all of posts and their categories.
Tables:
Posts: id, content, category_id, etc
Categories: id,name
Here's my code
Models:
class Posts extends Eloquent
{
public static $table = 'posts';
public function categories()
{
return $this->belongs_to('Categories');
}
}
class Categories extends Eloquent
{
public static $table = 'categories';
public function posts()
{
return $this->has_many('posts');
}
}
My controller
public function get_posts()
{
$posts = Posts::with('categories')->all();
return View::make('admin.posts')
->with('title', 'Posts')
->with('posts', $posts);
}
My view
#foreach($posts as $post)
<tr>
<td>{{ $post->title }}</td>
<td>{{ $post->categories->name }}</td>
<td><small> {{$post->updated_at}} </small></td>
<td>
<button>
{{HTML::link_to_route('edit_post','Edit',array($post->id))}}
</button>
{{Form::open('admin/delete','Delete')}}
{{Form::hidden('id', $post->id)}}
<input type="submit" name="edit_post" value="Delete"/>
{{Form::close()}}
</td>
</tr>
#endforeach
ERROR:
Error rendering view: [admin.posts]
Trying to get property of non-object
I am a newbie, please help me solve this issues
{{ $post->categories->name }} before test is categories exists
Example:
#if( ! empty($post->categories))
<td>{{ $post->categories->name }}</td>
#else
#end if
Aesis.
Just use ::all() instead of ::with(..)->all()
categories is an array as you are using a has_many relationship. There are many categories, hence an array is returned, so to access it you have to index it like an array
the correct solution would be
$post->categories[0]->name
Are you using Laravel 4? First the syntax for declaring relationship is hasMany and belongsTo, in camel case. Check it out in Laravel documentation
In view, check if categories are empty collection, ie., whether post has its category:
#if($post->categories->count())
<td>{{ $post->categories->name }}</td>
...
#endif
By the way, I would use singular form as model class name, like Post and Category instead of plural forms. And in Post class I would define inverse one-to-many relationship with singular form, to show there's only one entry in category table for this given Post.
public function category()
{
return $this->belongsTo('Category');
}

Categories