how can I get data from multiple related tables in Laravel - php

I have three tables: events - admins - dependencies
The relationship between them is the following:
a dependency has many admins, an admin has many events
like that:
I'm trying to show the name of the dependency to which the admin that created the event belongs.
How could I bring data with Laravel from this three tables?
controller:
class WelcomeController extends Controller
{
public function evento($slug){
$event = Event::where('slug', $slug)->first();
return view('evento', compact('event'));
}
Event model:
class Event extends Model
{
protected $fillable = [
'admin_id', 'place_id', 'name', 'slug', 'excerpt', 'body', 'status', 'file'
];
public function admins(){
return $this->belongsTo('App\Admin', 'admin_id');
}
Admin model:
protected $fillable = [
'name', 'email', 'password', 'cargo', 'dependence_id'
];
public function dependencyAdmin(){
return $this->belongsTo(Dependence::class);
}
Dependence Model:
class Dependence extends Model
{
protected $fillable = [
'name', 'slug'
];
public function adminsDependence(){
return $this->hasMany(Admin::class);
}
So I try to show it in the view, but it does not work:
<div class="panel-heading">
Dependencia:
{{$event->admins->dependencyAdmin->name}}
</div>

The problem is that you're only retrieving the event model without loading the relationship. See here for more explanation
$event = Event::where('slug', $slug)->first();
$eventAdmins = $event->admins()->get();
$eventAdminDependency = $eventAdmins->dependencyAdmin()->get();

Related

Is there a way to get a nested Eloquent model based on ids from another table?

Hey there stackoverflow
I am currently building a course application as part of my laravel project.
My problem lies in how the eloquent handle model relations, i'm still kinda new to eloquent, so hopefully you can answer my question.
The structure
The Course has many episodes and each episode has many sections.
Which means I have 3 tables in the DB. Courses -> course_episodes -> course_episode_sections
ID table is where i connect courses with users - course_users.
Right now i can create courses and and put in all the data correctly.
The Problem
I need to retrieve all the courses and its nested children that the user has bought, which is connected in the course_users table with columns course_id and user_id
Course structure
Same stucture in DB
course: {
name: null,
sub_title: null,
estimate: null,
trailer: null,
type: null,
text: null,
course_episodes: [
{
name: null,
section: [
{
order: null,
type: null,
content: null,
},
]
},
]
}
Model Pictures
My models as of right now.
class CourseUsers extends Model {
protected $fillable = [
'id',
'course_id',
'user_id',
'active',
];
protected $hidden = [
'deleted_at',
'updated_at',
'deleted_at'
];
public function courses()
{
return $this->belongsToMany(Course::class);
}
public function user(){
return $this->belongsTo(User::class);
}
public function scopeFindForUserId($query, $userId)
{
return $query->where(function ($q) use ($userId) {
$q->where(function ($q) use ($userId) {
$q->where('user_id', $userId);
});
});
}
Course model
class Course extends Model{
protected $fillable = [
'id',
'name',
'sub_title',
'type',
'estimate',
'trailer',
'gateway_id',
'text',
'active',
];
protected $hidden = [
'deleted_at',
'updated_at',
'deleted_at'
];
public function courseEpisode()
{
return $this->hasMany(CourseEpisode::class);
}
public function courseUsers() {
return $this->hasMany(CourseUsers::class);
}
public function scopeActive(Builder $builder)
{
return $builder->where('active', true);
}
Course episode Model
class CourseEpisode extends Model implements HasMedia {
use HasMediaTrait;
protected $fillable = [
'id',
'course_id',
'order',
'name',
];
protected $hidden = [
'deleted_at',
'updated_at',
'deleted_at'
];
public function course()
{
return $this->belongsTo(Course::class);
}
public function courseSection()
{
return $this->hasMany(CourseEpisodeSection::class);
}
Course episode sections
class CourseEpisodeSection extends Model {
protected $fillable = [
'id',
'course_episode_id',
'order',
'type',
'content'
];
protected $hidden = [
'deleted_at',
'updated_at',
'deleted_at'
];
public function courseEpisode()
{
return $this->belongsTo(CourseEpisode::class);
}
According to your explanation, course_users table holds many-to-many relationship between Course and User model. In case of a many-to-many relationship, you actually don't need a CourseUser model. This kind of table which holds many-to-many relationship is called pivot table. Read more from the Official Documentation
I am defining only the relationships with your Course, User, CourseEpisode, CourseEpisodeSection models.
Course.php
class Course extends Model
{
public function courseEpisodes()
{
return $this->hasMany(CourseEpisode::class);
}
public function users()
{
return $this->belongsToMany(User::class,'course_users')->withPivot('active');
}
}
CourseEpisode.php
class CourseEpisode extends Model
{
public function courseSections()
{
return $this->hasMany(CourseSection::class);
}
}
User.php
class User
{
public function courses()
{
return $this->belongsToMany(Course::class,'course_users')->withPivot('active');
}
}
If you want to get all the children relationships from a user, use nested eager loading :
$user_with_nested_course_data = User::with('courses.courseEpisodes.courseSections')->find($id);

Laravel belongs returns none

I have a user model, which can have many reports, and a report model obviously belonging to a user, whenever one is created.
However when I use return $this->belongsTo('App\User') on the report model No user is returned even when I have the correct user_id on the report, and correct id on the user table.
User
protected $fillable = [
'name', 'email', 'password',
];
public function reports()
{
return $this->hasMany('App\Report');
}
Report
protected $fillable = [
'user_id', 'title', 'detail',
];
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
I've solved it simply by using $report->user, instead of calling it like a function via $report->user()

Laravel issue on calling belongsToMany relationship

I have a project about quizzes and their questions,
I don't know why but when i'm trying to get the quiz's questions i get
this error
This are my files and scripts:
Route web.php file:
Route::get('/admin/quizzes/{id}/questions', 'AdminQuizzesController#questions')->name('admin.quizzes.questions')
Model Quiz.php file:
class Quiz extends Model
{
protected $dates = [ 'start_at', 'end_at', 'created_at', 'updated_at', 'deleted_at'];
protected $fillable = [
'title', 'category_id', 'level_id', 'is_active', 'start_at', 'end_at'
];
public function questions(){
return $this->belongsToMany('App\Question');
}
}
Model Question.php file:
class Question extends Model
{
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
protected $fillable = [
'title', 'correct_answer', 'category_id', 'level_id'
];
public function quiz(){
return $this->belongsTo('App\Quiz');
}
}
Controller AdminQuizzesController.php file:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Quiz;
class AdminQuizzesController extends Controller
{
public function questions($id)
{
$quiz = Quiz::findOrFail($id);
$questions = $quiz->questions;
return view('admin.quizzes.questions.index', compact('quiz', 'questions'));
}
}
the answer of #MazinoSUkah solved my problem.
just did 'composer dump-autoload' in my cmd
AFAIK composer dump-autoload regenerates the list of all classes that need to be included in the project (autoload_classmap.php). Ideal for when you have a new class inside your project or changed/renamed a class file. Hope it helps.

Laravel - Eloquent attach() not working for models

TL;DR
Trying to get three models to interact using eloquent for a rest api.
User - belongsToMany(pulls)
Pull - belongsToMany(user) && belongsToMany(boxes)
Box - belongsToMany(pulls)
The pull_user table is working perfectly, I can just attach a user after I save a pull. Saving a box works fine but the attach doesn't work/enter anything into the pivot table (I get no errors though).
The Problem
I can't get a pivot table that associates two of my models together to attach() after a save. I have the three models listed above, the pivot is working for pull_user but not for pull_box even though the save for box is working perfectly. I am able to save a box without an error but the association just never occurs (no error).
The Code
pull_box.php
class PullBox extends Migration
{
public function up()
{
Schema::create('pull_box', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('pull_id');
$table->integer('box_id');
});
}
public function down()
{
Schema::dropIfExists('pull_box');
}
}
Pull.php
class Pull extends Model
{
protected $fillable = ['from', 'to', 'runit_id', 'start_time', 'end_time', 'box_count', 'pull_status', 'audit_status', 'status', 'total_quantity', 'accuracy'];
public function users(){
return $this->belongsToMany('App\User');
}
public function boxes(){
return $this->belongsToMany('App\Box');
}
}
Box.php
class Box extends Model
{
protected $fillable = ['user_id','from', 'to', 'runit_id', 'start_time', 'end_time', 'pull_id', 'total_quantity', 'status', 'accuracy'];
public function pulls(){
return $this->belongsToMany('App\Pull');
}
}
BoxController.php
public function store(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer',
...
]);
$user_id = $request->input('user_id');
...
$box = new Box([
'user_id' => $user_id,
...
]);
$pull = Pull::whereId($pull_id)->first();
if($box->save()){
$pull->boxes()->attach($box->id);
$box->view_box = [
'href' => 'api/v1/box/' . $box->id,
'method' => 'GET'
];
$message = [
'msg' => 'Box created',
'box' => $box,
'pull' => $pull_id
];
return response()->json($message, 201);
}
$response = [
'msg' => 'Box creation error, contact supervisor',
];
return response()->json($response, 404);
}
The Solution
I need to know how I can get this association working. I am going to need to add a new layer in under the pull for Item, but I don't want to move one before I solve this. I think that my problem has to stem from a syntactical/logical error on my part but I can't see it. There are a bunch of questions on SO that are very close to giving me a solution, but after reading them I wasn't able to solve my problem.
Any help is appreciated.
Try renaming your pull_box table to box_pull, pivot tables on laravel must be in alphabetical order. If you want to use custom name on pivot table you have to extends your pivot, for example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class PullBox extends Pivot
{
protected $table = 'pull_box';
}
And your many to many relationships:
class Pull extends Model
{
protected $fillable = ['from', 'to', 'runit_id', 'start_time', 'end_time', 'box_count', 'pull_status', 'audit_status', 'status', 'total_quantity', 'accuracy'];
public function users(){
return $this->belongsToMany('App\User');
}
public function boxes(){
return $this->belongsToMany('App\Box')->using('App\PullBox');
}
}
class Box extends Model
{
protected $fillable = ['user_id','from', 'to', 'runit_id', 'start_time', 'end_time', 'pull_id', 'total_quantity', 'status', 'accuracy'];
public function pulls(){
return $this->belongsToMany('App\Pull')->using('App\PullBox');
}
}

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();

Categories