Laravel Relationship with Eloquent - laravel-5

I have two tables named products_description with primary key products_id and second table orders_products with foreign key products_id that link these two tables. We can say that a product can be in many orders.
I have created the following models for both tables.
namespace App;
use Illuminate\Database\Eloquent\Model;
class products_description extends Model
{
protected $table = "products_description";
protected $primaryKey = "products_id";
public function orders_products()
{
return $this->belongsTo('App\Orders_product','products_id','products_id');
return $this->hasMany(Orders_product::class);
}
}
and
namespace App;
use Illuminate\Database\Eloquent\Model;
class Orders_product extends Model
{
protected $primaryKey = "orders_products_id";
}
The following code in my controller class
class products_controller extends Controller
{
public function show1(Products_description $Products_description)
{
return view('products.show',compact('Products_description'));
}
}
The following code in my show.blade.php file
#extends('layout')
#section('content')
{{ $Products_description->products_name }}
#foreach($Products_description->orders_products as $Orders_product)
{{ $Orders_product->orders_id }}
#endforeach
#stop
Where I want to display the product name first and then the order ids in which this products exists. But I am getting the following error. Without foreach loop, the product name is displaying fine.
Trying to get property of non-object (View: C:\wamp\www\laravel1\resources\views\products\show.blade.php)
in 0bb3f93ed324818ac22ad70d47add00a1c4f8a7c.php line 11
at CompilerEngine->handleViewException(object(ErrorException), '1') in PhpEngine.php line 44
at PhpEngine->evaluatePath('C:\wamp\www\laravel1\storage\framework\views/0bb3f93ed324818ac22ad70d47add00a1c4f8a7c.php', array('__env' => object(Factory), 'app' => object(Application), 'errors' => object(ViewErrorBag), 'Products_description' => object(products_description))) in CompilerEngine.php line 59
at CompilerEngine->get('C:\wamp\www\laravel1\resources\views/products/show.blade.php', array('__env' => object(Factory), 'app' => object(Application), 'errors' => object(ViewErrorBag), 'Products_description' => object(products_description))) in View.php line 149

first this function have two returns, should remove first one:
public function orders_products()
{
return $this->belongsTo('App\Orders_product','products_id','products_id');
return $this->hasMany(Orders_product::class);
}
then in you controller function :
public function show1(Products_description $Products_description)
{
return view('products.show',compact('Products_description'));
}
you can't just compact('Products_description'), because it's an instance.
public function show1(Products_description $Products_description)
{
$products = $Products_description->all();
return view('products.show',compact('products'));
}
above is what you need , or just $products = $Products_description->find($productID);

I figured it out that I was using two relationships belongsTo and hasMany in my products_description model and was not using foreign_key and local_key in my hasMany relationship. Which was actually the problem. I removed the belongsTo relation and added the foreign_key and local_key to hasMany relation and it worked like a charm.

Related

Loading a belongs to relationship inside of a laravel resource collection

I'm having some issues loading my relationships into a ResourceCollection to be consumed by an API, I want to load blogs that each belong to a category.
The blog model which uses a belongsTo relationship
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class BlogPost extends Model {
use HasFactory, SoftDeletes;
protected $fillable = [
'title',
'content',
'seo_title',
'seo_content',
];
public function categories(): BelongsTo {
return $this->belongsTo(BlogCategory::class);
}
}
The Category model has a hasMany to blogs
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class BlogCategory extends Model {
use HasFactory;
protected $fillable = [
'slug'
];
public function blogs(): HasMany {
return $this->hasMany(BlogPost::class);
}
}
Inside of the blog_post migration, I added a foreign key to blog_categories
$table->foreignId('category_id')->constrained('blog_categories');
Then, in my BlogPost ResourceCollection I tried loading the relationship,
#[ArrayShape(['data' => "\Illuminate\Support\Collection", 'category' => AnonymousResourceCollection::class])] public function toArray($request): array {
return [
'data' => $this->collection,
'category' => BlogCategoryCollection::make($this->whenLoaded($this->categories))
];
}
I call the collection inside of the index function of my controller
public function index(): BlogPostCollection
{
return new BlogPostCollection(BlogPost::all());
}
And when I hit the api/blogs endpoint I get the error :
Property [categories] does not exist on this collection instance.
Managed to fix it in the end.
Changed the BlogPostResourceCollection to the following
return [
'data' => $this->collection,
'categories' => BlogCategoryCollection::collection($this->whenLoaded('categories'))
];
seems to work in the end.

error when attempting to seed pivot table using Laravel

I have just created a many-to-many relationship between the models Project and Features using Laravel however I receive the following error when attempting to run the seed script.
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'table.feature_projects' doesn't exist
The table in use is named features_project which is the default name given.
Inserting the seed data manually does return the relational data to the view as expected.
SEED
class FeaturesProjectTableSeeder extends Seeder
{
public function run()
{
$features_project = new \App\FeatureProject ([
'project_id' => '1',
'features_id' => '1'
]);
$features_project->save();
}
}
Project
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Project extends Model {
public function features() {
return $this->belongsToMany('App\Features')->withTimestamps();
}
}
Features
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Features extends Model
{
public function projects() {
return $this->belongsToMany('App\Project')->withTimestamps();
}
}
CONTROLLER
class ProjectController extends Controller
{
public function getProject($id)
{
$project = Project::where('id', $id)->get();
return view('other.project', ['project' => $project]);
}
}
ROUTE
Route::get('project/{id}', [
'uses' => 'ProjectController#getProject',
'as' => 'other.project'
]);
VIEWS
#foreach($project->features as $feature)
<dd class="col-sm-8">{{ $feature->name }}</dd>
#endforeach
Firstly some misunderstanding in naming, your table name should be feature_project, in many to many relationships the models are in alphabetical order. Secondly models are not plural, so your Features.php model should be named Feature.php. Which will resolve in Laravel using the table feature_project for the pivot and features for the model.
For your own sake, learn how Laravel name models and tables, else relationships are gonna be tricky. Which is described in the documentation.
You should not create pivot models, this is handled by assigning features to projects or vice versa. Therefor your seeder should look something like this, it could be you should assign some attributes to the projects and features before it will work.
class FeaturesProjectTableSeeder extends Seeder
{
public function run()
{
$features = factory(Feature::class)->create();
$projects = factory(Project::class)->create();
$projects->each(function (Project $project) {
$project->features()->saveMany($features);
});
}
}

Cannot establish relationship between two tables in Laravel

I want to create a relation between lising and attribute table in laravel for that i have used following code to establish relationship between them but the data in my view is not coming from both the tables. I'm getting following error:
Call to undefined relationship [adListAttributes] on model
[App\Models\AdListing].
Here listing can have as many attribute associated with and attributes
can be associated to many listings
ad_listings:
id
title
name
date
ad_list_attributes table :
id
listing_id
name
namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\Model;
class AdListAttribute extends Model
{
protected $table = "ad_list_attributes";
public function Listings()
{
return $this->belongsToMany('AdListing', 'id', 'listing_id');
}
}
namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\Model;
class AdListing extends Model
{
protected $table = "ad_listings";
public function Attributes()
{
return $this->belongsToMany('AdListAttribute', 'listing_id', 'id');
}
}
Problem is that you are using belongsToMany in both the models.This will cause a problem.
In AdListAttribute model,
public function listing_information()
{
return $this->belongsTo('App\AdListing', 'id', 'listing_id');
}
In AdListing model,
public function adlisting_attributes()
{
return $this->hasMany('App\AdListAttribute', 'listing_id', 'id');
}
You can get the results using,
$response = AdListing::get();
if($response->adlisting_attributes)
{
foreach($response->adlisting_attributes as $attribute)
{
echo $attribute->name;
}
}
Problem is that ur not calling the relationship with the right name i assume
$listings = AdListing::with('Attributes')->get();
Update :
Try this :
use App\Models\AdListAttribute;
//
return $this->belongsToMany(AdListAttribute::class, 'listing_id', 'id');
Same for other model, then try

Class 'App\Models\Registration' not found even though i have import it

Class 'App\Models\Registration' not found, i have import Registration class
i am trying to save student_id with it corresponding subjects array
When i dump dd($request->all()) i get the excepted results which is
"student_id" => "1"
"subjects" => array:2 [▼
0 => "1"
1 => "2"
]
but i get an exception when i trying saving into the database
this is my registration scheme
Schema::create('registrations', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('student_id')->index();
$table->string('subjects');
$table->foreign('student_id')->references('id')->on('students');
$table->timestamps();;
});
this is my registration model
class Registration extends Model
{
protected $table = 'registrations';
protected $fillable = ['student_id','subjects'];
protected $cast = [
'student_id' => 'Integer',
'subjects' => 'array',
];
public function student(){
$this->belongsTo(Student::class);
}
public function subjects()
{
$this->hasMany(Subject::class);
}
}
i am using checkbox array to get the subjects
<input class="form-check-input" name="subjects[]" value="{{$subject->id}}" type="checkbox">
this is registration controller code, i have imported registration model
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Models\Registration;
use App\Http\Controllers\BaseController;
class RegistrationController extends BaseController
{
public function store(Request $request)
{
$registration = Registration::create(request()->validate([
'student_id' => 'required|integer',
'subjects' => 'required',
'subjects.*'=> 'accepted',
]));
}
i want to save the student_id with the subjects array
student subjects
1 [2,4,5]enter code here
I think you need to add a namespace.
<?php
namespace App\Models;
class Registration extends Model { ... }
?>
Also your model must be stored inside the directory App/Models/Registration.php.
i think you create your Registration model in App directory...please check your directory.then use
use App\Registration;
If It on App\Models directory then In Registration Model,
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Registration extends Model { }

Laravel: One to Many Poly relation not updating automatically

3 types of posts: Personal, Business & Nature.
Below is the Post Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
Relation::morphMap([
'Personal' => 'App\Personal',
'Business' => 'App\Business',
'Nature' => 'App\Nature',
]);
class Post extends Model
{
public function postable()
{
return $this->morphTo();
}
}
Below is the Personal Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Personal extends Model
{
public function posts()
{
return $this->morphMany(Post::class,'postable');
}
}
Likewise Busines & Nature models.
When I manually enter the data in phpMyAdmin, the tinker shows the result as required, but when I create a post from front-end (via form), the posts table remains unchanged.
I tried googling, but nothing works! :(
Below is the PersonalController
public function create()
{
if(Auth::guest()){
return redirect()->route('login');
}
$sectors = Sector::all();
$cities = City::all();
$ranges = Range::all();
return view('front.personal-register',compact('sectors','cities','ranges'));
}
public function store(Request $request)
{
$this->validate($request,[
"sectors" => "required",
"cities" => "required",
"ranges" => "required",
"g-recaptcha-response" => "required|captcha"
]);
$franchisee = new Personal;
$franchisee->user_id = Auth::user()->id;
$franchisee->save();
$franchisee->sectors()->sync($request->sectors);
$franchisee->cities()->sync($request->cities);
$franchisee->ranges()->sync($request->ranges);
return redirect(route('personal.index'))->with('message','Thank You! Your post has been added');
}

Resources