I got stacked in laravel eloquent relationships. Here's the scenario:
I have 4 tables in my database:
Categories,
Courses,
Lessons, and
Lesson_items.
I have 3 more tables:
category_course,
course_lesson, and
lesson_item_lesson.
Now, I have these codes:
Category.php - model
class Category extends Model
{
public function courses(){
return $this->belongsToMany('App\Course');
}
}
routes.php - routes
Route::get('/category/{id}', [
'uses' => 'LearnController#getCategories'
]);
MyController.php - controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Category;
use App\Lesson;
class LearnController extends Controller
{
public function getCategories($id){
$categories = Category::find($id);
$lessons = Lesson::find($categories);
return view('categories', compact('categories', 'lessons'));
}
}
Now, The result that I want is this:
Really need your help guys.
You need nested eager laoding
Category.php
class Category extends Model
{
public function courses(){
return $this->belongsToMany('App\Course');
}
}
Course.php
class Course extends Model
{
public function lessons(){
return $this->belongsToMany('App\Lesson');
}
}
Lesson.php
class Lesson extends Model
{
public function lessonItems(){
return $this->belongsToMany('App\LessonItem');
}
}
LessonItem.php
class LessonItem extends Model
{
public function lessons(){
return $this->belongsToMany('App\Lesson');
}
}
Then in controller
class LearnController extends Controller
{
public function getCategories($id){
$categories = Category::with('courses.lessons.lessonItems')->find($id);
return view('categories', compact('categories'));
}
}
Edit
You need some kind of this construction
#foreach ($category->courses as $course) {
#foreach ($course->lessons as $lesson) {
#foreach ($lesson->lessonItems as $item) {
#endforeach
#endforeach
#endforeach
Related
ErrorException
Trying to get property 'category_name' of non-object (View: D:\xampp\htdocs\e-catalog\resources\views\backend\pages\gmproducts.blade.php)
This is my blade code below.
<tbody>
#foreach($gmproducts as $no => $gm)
<tr>
<td>{{$no+1}}</td>
<td>{{$gm->type}}</td>
<td>{{$gm->gmcategories->category_name}}</td>
<td>{{$gm->gram}}</td>
<td>{{$gm->carat}}</td>
<td>#currency($gm->price)</td>
<td><a class="test-popup-link" href="{{url('p_goldmart/'.$gm->file)}}">Preview</a></td>
<td>
<i class="fa fa-edit"></i>
<i class="fa fa-trash-o"></i>
</td>
</tr>
#endforeach
</tbody>
This is my model Gmcategories & Gmproducts.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Gmcategories extends Model
{
protected $table = "gmcategories";
protected $fillable = ['category_name'];
public function gmproducts()
{
return $this->hasOne('App\Gmproducts');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Gmproducts extends Model
{
use SoftDeletes;
protected $table = "gmproducts";
protected $fillable = ['type', 'category_id', 'gram', 'carat', 'price', 'file'];
protected $dates = ['deleted_at'];
public function gmcategories()
{
return $this->belongsTo('App\Gmcategories');
}
}
This is my controller.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Gmproducts;
use App\Gmcategories;
use File;
class GmproductsController extends Controller
{
public function index()
{
$gmproducts = Gmproducts::orderBy('id', 'desc')->get();
$trash = Gmproducts::orderBy('deleted_at', 'desc')->onlyTrashed()->count();
return view('backend.pages.gmproducts', compact('gmproducts', 'trash'));
}
public function create()
{
$gmcategories = Gmcategories::all();
return view('backend.pages.create', compact('gmcategories'));
}
Just info, I just rename my model and controller. Does it have any effect? Thanks.
// Gmcategories model
public function gmproducts()
{
return $this->hasOne('App\Gmproducts', 'category_id');
}
// Gmproducts model
public function gmcategories()
{
return $this->belongsTo('App\Gmcategories', 'category_id');
}
Your BuildImage model should be
Get the source type of the Building Image.
public function type() {
return $this->hasOne('App\BuildingType',"id","source");
}
And BuildingType Model should be
Get the Building Image that owns the building type.
public function buildingImage()
{
return $this->belongsTo('App\BuildingImage',"source","id");
}
I want to pass $defaultFrom from NewsletterController.php:
<?php
namespace App\Http\Controllers;
use App\Mail\NewsletterMail;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
class NewsletterController extends Controller
{
public function send()
{
$defaultFrom = 'newsletter#stuttard.de';
DB::table('newsletter_mails')->insert(['from' => $defaultFrom]);
$emails = DB::select('select * from newsletters order by id desc');
foreach ($emails as $email) {
Mail::to($email)->send(new NewsletterMail());
}
}
}
to NewsletterMail.php:
<?php
namespace App\Nova;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
class NewsletterMail extends Resource
{
public function fields(Request $request)
{
return [
ID::make(__('ID'), 'id')->sortable(),
Text::make('From', 'from')->default($defaultFrom)->placeholder($defaultFrom),
];
}
}
I've tried to put public $defaultFrom; above the fields() function or call new NewsletterMail($defaultFrom) but this seems to be wrong syntax. Sorry, I'm a bit new to Laravel.
I assume that you have Newsletter model. Move $defaultFrom to model as public const DEFAULT_FROM = 'newsletter#stuttard.de';. After doing this, you can call it's value in both places using Newsletter::DEFAULT_FROM.
Post Model
<?php
namespace App\Model\User;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function tags(){
return $this->belongsToMany('App\Model\User\Tag','post__tags', 'post_id', 'tag_id');
}
public function categories() {
return $this->belongsToMany('App\Model\User\Category','category__posts','post_id', 'category_id');
}
}
Category Model
<?php
namespace App\Model\User;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function posts(){
return $this->belongsToMany('App\Model\User\Category','category__posts', 'post_id', 'category_id');
}
}
Tag Model
<?php
namespace App\Model\User;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
public function posts() {
return $this->belongsToMany('App\Model\User\Post','post__tags','post_id','tag_id');
}
}
PostController.php
public funcion store()
{
// do validation here
try{
$post = new Post;
$post->title = $request->title;
$post->subtitle = $request->subtitle;
$post->slug = $request->slug;
$post->body = $request->body;
$post->status = 1;
$post->save(); // This works correct
$post->tags->sync($request->tags); // Not working
$post->categories->sync($request->categories); // Not working
}
catch(\Exception $e){
return redirect(route('post.index'))->with('message', 'Error Adding Post into system!'.$e->getMessage()); // getting Message "Method sync does not exist. "
}
}
Sync is a method on the builder instance, you're using it on the collection.
// change your code like this
$post->tags()->sync($request->tags);
$post->categories()->sync($request->categories);
You need to use the following:
$post->tags()->sync($request->tags);
$post->categories()->sync($request->categories);
Don't forget the () in tags and categories
$post->categories without () is a Collection instance.
$post->categories() is a belongsToMany instance
I'm using Laravel 5.2.
I have 3 tables (writters, publishers and categories) all of the is One to Many Relationships with table named books.
I'm not really sure what the problem is, but everytime i call the the column from 2 of them (nama_penerbit from publishers table and nama_kategori from categories table)from my view blade, it throws me an error Trying to get property of non-object
Here is my models
Book.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
protected $fillable = [
'judul',
'label',
'isbn',
'tanggal_terbit',
'status',
'id_penulis',
'id_penerbit',
'id_kategori',
];
// Book with Writter
public function writter()
{
return $this->belongsTo('App\Writter', 'id_penulis');
}
// Book with Publisher
public function publisher()
{
return $this->belongsTo('App\Writter', 'id_penerbit');
}
// Book with Category
public function category()
{
return $this->belongsTo('App\Writter', 'id_kategori');
}
}
Publisher.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Publisher extends Model
{
protected $fillable = [
'nama_penerbit',
];
// Relation Book with Publisher
public function book() {
return $this->hasMany('App\Book', 'id_penerbit');
}
}
Writter.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Writter extends Model
{
protected $fillable = [
'nama_penulis',
];
// Relation Book with Writter
public function book() {
return $this->hasMany('App\Book', 'id_penulis');
}
}
Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $fillable = [
'nama_kategori',
];
// Relation Book with Category
public function book() {
return $this->hasMany('App\Book', 'id_kategori');
}
}
my-view.blade.php
<span>{{ $book->writter->nama_penulis }}</span> // works like a charm
<span>{{ $book->publisher->nama_penerbit }}</span> // throw me an error
<span>{{ $book->category->nama_kategori }}</span> // throw me an error
My question is why nama_penerbit and nama_kategori throw a error while the other one works well
Any sugestion?
You're using Writter model for all three relationships, so fix these relationships by setting correct models:
// Book with Publisher
public function publisher()
{
return $this->belongsTo('App\Publisher', 'id_penerbit');
}
// Book with Category
public function category()
{
return $this->belongsTo('App\Category', 'id_kategori');
}
My Route
Route::get('news-logs', 'Backend\ChangeLog\ChangeLogController#changeLogNews')->name('change-log-news');
My Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class News extends Model
{
protected $table = 'news';
use \Venturecraft\Revisionable\RevisionableTrait;
protected $revisionCreationsEnabled = true;
protected $revisionEnabled = true;
public static function boot()
{
parent::boot();
}
public function revisionHistory(){
$news = News::all();
$history = $news->revisionHistory;
}
public function getRouteKeyName()
{
return 'slug';
}
public function months($year) {
$queryResult = DB::table('news')->select(DB::raw('MONTH(order_date) as month'), DB::raw('YEAR(order_date) as year'))->where(DB::raw('YEAR(order_date)'), $year)->orderBy(DB::raw('MONTH(order_date)'))->get();
$months = collect($queryResult)->unique('month');
return $months;
}
}
My Controller
<?php
namespace App\Http\Controllers\Backend\ChangeLog;
use App\Models\News;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ChangeLogController extends Controller
{
public function changeLogNews(){
$news = News::all();
$history = $news->revisionHistory;
dd($history);
return view('backend.change-log.history',compact('history'));
}
}
My View
#foreach($history->revisionHistory as $log )
<li>
{{ $log->userResponsible()->name }} changed {{ $log->fieldName() }} from {{ $log->oldValue() }} to {{ $log->newValue() }}</li>
#endforeach
Now When ever I load the page, it says - "Property [revisionHistory] does not exist on this collection instance". I would like to get any help form your side.
Thank You
The $history doesn't have a revisionHistory property. The $history is the result of $news->revisionHistory.