Why can't I use method on relation in laravel? - laravel

I wanna using method on relation in laravel but show error[Method Illuminate\Database\Eloquent\Collection::getMessage does not exist.].
Error was changed to Call to a member function getMessage() on null when I rewrite {{$item->board2->getMessage()}} to {{$item->aaaaaaaa->getMessage()}} so I think relation was succeed.
I have no Idea what's wrong.
please give me advice.
Board2.php(model)
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Board2 extends Model
{
protected $table = 'boards2';
protected $fillable = [
'person2_id',
'message'
];
public function person2()
{
return $this->belongsTo('App\Person2');
}
public function getMessage()
{
return $this->message;
}
}
Person2(model)
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Person2 extends Model
{
protected $table = 'people2';
protected $fillable = [
'name'
];
public function board2()
{
return $this->hasMany('App\Board2', 'person2_id');
}
}
View
<ul>
#foreach($items_p2 as $item)
<li>
{{$item->name}}
</li>
<li>
{{$item->board2->getMessage()}}
</li>
#endforeach
</ul>
controller
・
・
・
public function show2()
{
$items_p2 = Person2::all();
$data = [
'items_p2' => $items_p2
];
return view('Review.show2', $data);
}
migration files
class CreatePeople2Table extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('people2', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBoards2Table extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('boards2', function (Blueprint $table) {
$table->increments('id');
$table->integer('person2_id');
$table->text('message');
$table->timestamps();
});
}

first:
in order to get the relation data you should load it first ...
$items_p2 = Person2::with('board2')-> all();
second: in your blade file
{{$item->board2->getMessage()}}
$item->board2 return a collection not a single board, so you should put it in foreach as well
#foreach($items_p2 as $item)
<li>
{{$item->name}}
</li>
<li>
#foreach($item->board2 as $board)
<li>
{{$item->board2->getMessage()}}
<li>
#endforeach
</li>
#endforeach
</ul>

Inside Board2.php(model) file, you have defined the method getMessage(), the method is loaded on the instance of the model and not the array of models (in Laravel's case, multiple models are loaded in a collection).
Inside Person2(model) file, you have defined the relation board2() which is linked to Board2 model via HasMany Relation. The catch is that HasMany relation, as the name suggests will load collection from the db and not a single instance of the model.
Try changing HasMany to HasOne inside Person2 model, your error should be resolved.

Accoring to the code you have written, each board2 record is connected to a single instance of person2, but on the other side, each person2 record is connected to a collection/array of board2 (not connected to single board2). This is the point keep in mind. Now let's proceed to next step.
Let's take a look in your view file. The code you wrote in view is
<ul>
#foreach($items_p2 as $item)
<li>
{{$item->name}}
</li>
<li>
{{$item->board2->getMessage()}}
</li>
#endforeach
</ul>
Here in $item->board2 , the board2 is not a single instance/record/model, rather it is a collection/array of multiple board2 instances/records/models. And each of that record/model will have the method "getmessage()" as you expected. So, the thing you have to do is, iterate through the records/models by making foreach to $item->board2, this way you will have the access to each single board2 record/model, then call the getMessage() method from that record/model. Let's modify the view code like this.
<ul>
#foreach($items_p2 as $item)
<li>
{{$item->name}}
</li>
<li>
#foreach( $item->board2 as $board )
{{$board->getMessage()}}
//this echo is just to break the line
echo '<br>';
#endforeach
</li>
#endforeach
</ul>
Hope it will work now. :)

You have to change this location. You write this in Person2 model
public function getMessage(){
return $this->message;
}

Related

questions regarding laravel sidebar

im new to laravel and i want to know how to make a dynamic sidebar.
Right now it looks like this
In my native language it means category - berrys, juice, candy - and each of them goes to a view, where there should be only products who have in the database one of these three in the "category" column.
My question are:
1)Can i do it with a foreach loop?
2)Do i need to make a model and controller for each of them and if i do what functions do i need?
3)How do i show only the produkcts that have the right category
Right now i have:
#foreach($products as $item)
<div class="col-sm-6 col-md-4">
<a href="details/{{$item['id']}}">
<div class="thumbnail">
<img src="images/{{$item['galerija']}}" alt="...">
<div class="caption">
<h3>{{$item['nosaukums']}}</h3>
<p>{{$item['cena']}}</p>
</div>
</div>
</a>
</div>
#endforeach
That shows every product. Do i need something similar?
More details.
In my controller:
function shop()
{
$data= Product::all();
return view('pages.shop',['products'=>$data]);
}
My moddel:
class Product extends Model{
protected $primaryKey = 'id';
public $timestamps = false;
protected $fillable = [
'nosaukums', 'cena', 'kategorija', 'galerija', 'apraksts',
];
}
Yes.
Since it's the same model, you only need one controller with one method (if you follow conventions this would be a show method).
Using a relation.
Due to the fact you're coding in your native language (which I cannot decipher), below example is a way of how you could do it.
P.S. In the case that a product can have more than one categories, you should convert the relation into a Many to Many using a pivot table.
Category model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function products(): HasMany
{
return $this->hasMany(Product::class);
}
}
Product model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
}
Web.php
Route::get('categories/{category}', [CategoryController::class, 'show'])->name('categories.show');
Sidebar view
Note: You can load $categories using a View Composer.
<div>
#foreach($categories as $category)
<a href="{{ route('categories.show', compact('category')) }}">
{{ $category->name }}
</a>
#endforeach
</div>
Category controller
<?php
namespace App\Http\Controllers;
use App\Models\Category;
class CategoryController extends Controller
{
public function show(Category $category)
{
$products = $category->products;
return view('categories.show', compact('products');
}
}

how can i handle the relations beetween products attributes and values?

i'm working on a Laravel/Livewire project
there are some products and services in this platform that user can order them.
the price of these products and services are changeable by their attributes . like size,color,quality and....
and i made a Many To Many relation between products and attributes.
but a can't handle it in my view where user should select that attributes before ordering
and my for each loop return wrong data . and i get this error :
Trying to get property 'pivot' of non-object .
my migration :
public function up()
{
Schema::create('attr_product', function (Blueprint $table) {
$table->foreignId('attr_id')->constrained();
$table->foreignId('product_id')->constrained();
$table->string('value')->nullable();
$table->string('price')->nullable();
$table->timestamps();
});
}
product model :
public function attr(){
return $this->belongsToMany(Attr::class)->withPivot(['value','price'])->withTimestamps();
}
attr model:
public function product(){
return $this->belongsToMany(Product::class)->withPivot(['value','price'])->withTimestamps();
}
my controller :
class SingleProduct extends Component
{
public $product;
public function mount($id){
$this->product=Product::with('attr')->findOrFail($id);
}
public function render()
{
return view('livewire.front.product.single-product')->extends('layouts.Default')->section('content');
}
}
my loop in blade :
#foreach($product->attr as $attr)
<div class="col-lg-4 col-sm-6 mt-3">
<h6 class="mb-2 text-black">{{$attr->title}}</h6>
<select class="custom-select shadow-none">
#foreach($attr as $av)
<option value="{{$av->pivot->price}}">{{$av->pivot->value}}</option>
#endforeach
</select>
</div>
#endforeach
before #foreach add
#php
dd($product)
#endphp
You can troubleshoot your $product Model and relations
The right syntax for withPivot should be parameters separated by comma, try this:
product model
public function attr(){
return $this->belongsToMany(Attr::class)
->withPivot('value','price')
->withTimestamps();
}
attr model:
public function product(){
return $this->belongsToMany(Product::class)
->withPivot('value','price')
->withTimestamps();
}

Laravel - hasMany() and belongsTo() not working correctly for me in #foreach loop

I got following error when I try to use this on my page
Trying to get property of non-object
I have two tables:
cvicenis
id
title
body
category_id
categories
id
name
My Cviceni model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Cviceni extends Model
{
public function category()
{
return $this->belongsTo('App\Category', 'id');
}
}
My Category model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function cviceni()
{
return $this->hasMany('App\Cviceni', 'category_id');
}
}
My controller:
public function index()
{
$cviceni = Cviceni::all();
return view('excercises.index', compact('cviceni'));
}
My index.blade:
#extends('layouts.app')
#section('content')
<div class="row">
<div class="col-sm-6 col-md-6 col-lg-3">
<h1>Přehled cvičení</h1>
#if(count($cviceni) > 0)
<ul>
#foreach ($cviceni as $c)
<li> {{ $c->category->name }}</li>
#endforeach
</ul>
#else
<h2>There is nothing to display</h2>
#endif
</div><!-- end of column -->
</div><!-- end of row -->
#endsection
If I use in my controller Cviceni::find(1) then I can get the value from $cviceni->category->name
But not when I use a foreach loop.
Can somebody help me please?
In the Cviceni model, I think you set up the foreign key is wrong. Your foreign key in the table is category_id, while you set up the relationship with foreign key is id. Try to replace the category() relationship with follow
public function category()
{
return $this->belongsTo('App\Category', 'category_id');
}
You need to eager load the models if you need them:
public function index()
{
$cviceni = Cviceni::with("category")->get();
return view('excercises.index', compact('cviceni'));
}

Trying to get property of non-object in Laravel Relationship

I have two tables in my database, an Articles table and a Users table. An Article is posted by a user and a foreign key exists called 'created_by' referring to the 'user_id' field in the Users table.
My Laravel models are as follows:
User model
class User extends Model
{
use Notifiable;
protected $primaryKey = 'user_id';
public function articles()
{
return $this->hasMany('App\Article', 'created_by', 'user_id');
}
}
Article Model
class Article extends Model
{
protected $primaryKey = 'article_id';
public function user()
{
return $this->belongsTo('App\User', 'created_by' 'user_id');
}
}
I have a view dashboard which displays all the articles and the name of the person who posted it and their image.
Dashboard Controller
<?php
namespace App\Http\Controllers;
use App\User;
use App\Article;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
public function index (Request $request)
{
if($request->session()->get('username')) {
$articles = Article::all();
return view('dashboard', compact('articles'));
}
else
return redirect('login');
}
}
And finally the section of my view I'm getting the 'Trying to get property of non-object' error for.
#foreach($articles as $article)
<div class="row">
<div class="col-lg-1"></div>
<div class="col-lg-9">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">{{ $article->title }} </h3>
</div>
<div class="panel-body">
<p>
{{ $article->content }}
<br><br> - {{ $article->user->first_name }}
</p>
</div>
</div>
</div>
<div class="col-lg-1"><center><br><br>
<img src="{{ asset('images/people/$article->user->image') }}" class="img-circle" alt="Person"></center>
</div>
</div><br><br>
#endforeach
It seems to be the $article->user->first_name that I am having trouble with. If I type $article->user alone, the page will load but nothing appears in that area.
Any ideas, I have been searching for solutions for the last two hours.
I think you need to specify that you want users to load with with the articles, like $articles = Article::with('user')->all();
Drop a dd($articles) right before the return statement and you'll see what you're actually dealing with.
$articles = Article::with('user')->get();
Edit
Try to check also if $article->user is null in the view because if there is no user assigned for an article then you will get "trying to get property of non object" error
so give an extra check when you access user's data.
{{ $article->user !== null ? $article->user->first_name : 'User Not Found' }}
Do this for user photo also
Please edit your controller, pls mark as answered thx.
<?php
namespace App\Http\Controllers;
use App\User;
use App\Article;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
public function index (Request $request, Article $articles)
{
if($request->session()->get('username')) {
return view('dashboard')->with('articles', $articles->all() );
}
else
return redirect('login');
}
}

Getting the name of the foreign key with eloquent

This must be very basic stuff but I can't seem to find out how to do it.
I have a one to many relationship between to tables: Unit and Army (an army contains many units) and these are my models:
class Army extends Eloquent {
protected $guarded = array();
public static $armies = array();
protected $table = 'armies';
public function units()
{
return $this->hasMany('Unit');
}
}
and:
class Unit extends Eloquent {
protected $guarded = array();
public static $units = array();
protected $table = 'units';
public function armies()
{
return $this->belongsTo('Army', 'army');
}
}
So, in my Unit table I have a row called"army" that contains the id of the army related to that unit and I want to show in my view a simple ul list in the following fashion (I want this to show on the unit index view):
<ul>
<li>Army 1 name
<li>Unit 1 of Army 1</li>
<li>Unit 2 of Army 1</li>
</li>
<li>Army 2 name
<li>Unit 1 of Army 2</li>
<li>Unit 2 of Army 2</li>
</li>
</ul>
To do this I have my unit controller like so:
class UnitsController extends BaseController {
protected $layout = 'master';
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
$units = Unit::all();
$this->layout->content = View::make('units.index', compact('units'));
}
/*Other stuff*/
}
And in my view (index.blade.php inside views/units):
<ul class="units">
#foreach($units as $unit)
{{$unit->army}}
<li>
{{ HTML::link(route('units.show', ['units' => $unit->id]), $unit->name)}}
</li>
#endforeach
</ul>
But {{$unit->army}} is just (of course) showing the id of the army, and I want the name, how do I do this?
Assuming you have set up your schema correctly: armies table has at least id(auto-increment) and units table has at least id(auto-increment) and army_id (integer, unsigned), then, try this:
Models
class Army extends Eloquent {
public function units()
{
return $this->hasMany('Unit');
}
}
class Unit extends Eloquent {
public function armies()
{
return $this->belongsTo('Army');
}
}
In your Controller
You want to get all armies with units:
$armies = Army::with('units')->get();
In your View you want to loop through the result set outputting the name of each army and its respective units
#foreach($armies as $army)
{{$army->name}}
<ul>
#foreach($army->units as $aunit)
<li>
{{ $aunit->name }}
</li>
#endforeach
</ul>
#endforeach
If that doesn't work, I'll eat my head.

Resources