Laravel BelongsToMany Error - Base table or view not found - laravel

I hope this thread find everyone healthy.
What is wrong with the following code? I am getting an error on my many to many relationship. For the past 4 hours i am stuck with this problem. I would be very thankful if you find the bug or source of problem.
Here is my code and tables:
Schema::create('products', function(Blueprint $table)
{
$table->increments('id');
$table->integer('category');
$table->string('thumbnail');
$table->string('images');
$table->string('logo');
$table->string('main_photo');
$table->timestamps();
});
//categories table
Schema::create('product_categories', function(Blueprint $table)
{
$table->increments('id');
$table->string('category');
});
//relationship table
Schema::create('product_productcategory', function(Blueprint $table)
{
$table->increments('id');
$table->integer('product_id'); // the id of the bear
$table->integer('productcategories_id'); // the id of the picnic that this bear is at
});
products model:
class Product extends Model
{
protected $table = 'products';
public function product_category() {
return $this->belongsToMany('App\product_category', 'App\product_productcategory', 'product_id', 'productcategories_id');
}
}
And pivot model
class product_category extends Model
{
protected $table = 'product_categories';
public function product() {
return $this->belongsToMany('App\Product', 'App\product_productcategory', 'productcategories_id', 'product_id');
}
}
Thanks in advance!
Updates: The problem is solved thanks to #mimo.
But now i want to translate the categories in different languages so i created a table like this:
Schema::create('category_translations', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('product_categories')->onDelete('cascade');
$table->integer('locale_id')->unsigned();
$table->foreign('locale_id')->references('id')->on('locales')->onDelete('cascade');
$table->unique(['category_id', 'locale_id']);
});
And my product categories with new relationship to the translations
class product_category extends Model
{
protected $table = 'product_categories';
public function product() {
//return $this->belongsToMany('App\Product', 'App\product_productcategory', 'productcategories_id', 'product_id');
return $this->belongsToMany('App\Product', 'product_productcategory');
}
public function translation($lang) {
return $this->hasMany('App\Category_Translation')->where('locale_id', '=', $lang);
}
}
And in category translation:
class Category_Translation extends Model
{
protected $table = 'category_translations';
public function product_category() {
return $this->belongsTo('App\product_category');
}
}
And finally my Product:
class Product extends Model
{
protected $table = 'products';
public function translation($lang) {
return $this->hasMany('App\Product_Translation')->where('locale_id', '=', $lang);
}
public function product_category() {
//return $this->belongsToMany('App\product_category', 'App\product_productcategory', 'product_id', 'productcategories_id');
//return $this->belongsToMany('App\product_category', 'product_productcategory');
return $this->belongsToMany('App\product_category', 'product_productcategory')->translation(1);
}
}
Now when i run:
$product = App\Product::find(1)->first();
echo $product->product_category;
I get error:
Call to undefined method Illuminate\Database\Query\Builder::translation()

Your migration file is wrong:
//relationship table
Schema::create('product_productcategory', function(Blueprint $table)
{
$table->integer('product_id')->unsigned()->index(); // the id of the bear
$table->foreign('product_id')->references('id')->on('products');
$table->integer('productcategories_id')->unsigned()->index(); // the id of the picnic that this bear is at
$table->foreign('productcategories_id')->references('id')->on('product_categories');
});
This code will made the relationship on the database level.
When you have 12 min free time you can check out this tutorial about many to many relationships in laravel:
https://laracasts.com/series/laravel-5-fundamentals/episodes/21
Update:
you need to update your relationships too:
class Product extends Model
{
protected $table = 'products';
public function product_category() {
return $this->belongsToMany('App\product_category', 'product_productcategory');
}
}
and:
class product_category extends Model
{
protected $table = 'product_categories';
public function product() {
return $this->belongsToMany('App\Product', 'product_productcategory');
}
}

Related

Laravel eloquent relations not working completely

I've a payment gateway, I want to access the product items after returning, so I created several tables Payments, Orders, OrderItems and configured the relationships between them.
Each Payment is for one Order and each Order contains several OrderItem and each OrderItem contains one product. Now I want to access each Product through an object of the Payment Model, which returns the following error.
Illuminate\Database\QueryException SQLSTATE[42S22]: Column not found:
1054 Unknown column 'orders.order_item_id' in 'field list' (SQL:
select products.*, orders.order_item_id as laravel_through_key
from products inner join orders on orders.id =
products.order_id where orders.order_item_id = 68 limit 1)
$product_order_item = $payment->order->order_items->map(function ($order_item) {
dd($order_item->product);
});
Payment Model:
protected $table = "payments";
protected $guarded = [];
public function order() {
return $this->belongsTo(Order::class);
}
Order Model:
protected $table = "orders";
protected $guarded = [];
public function payment() {
return $this->hasOne(Payment::class);
}
public function order_items() {
return $this->hasMany(OrderItem::class);
}
OrderItem Model:
protected $table = "order_items";
protected $guarded = [];
public function order() {
return $this->belongsTo(Order::class);
}
public function product() {
return $this->hasOneThrough(Product::class, Order::class);
}
Product Model:
protected $table = "products";
protected $guarded = [];
public function order_items() {
return $this->belongsToMany(OrderItem::class);
}
That is migrations:
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('CASCADE');
$table->unsignedInteger('amount');
$table->unsignedInteger('res_code');
$table->enum('status', ['paid', 'unpaid']);
$table->timestamps();
});
=====================================================
Schema::create('order_items', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('order_id');
$table->foreign('order_id')->references('id')->on('orders')->onDelete('CASCADE');
$table->unsignedBigInteger('product_id');
$table->foreign('product_id')->references('id')->on('products')->onDelete('CASCADE');
$table->unsignedInteger('price');
$table->timestamps();
});
===========================================================
Schema::create('payments', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('order_id');
$table->foreign('order_id')->references('id')->on('orders')->onDelete('CASCADE');
$table->enum('status', ['paid', 'unpaid']);
$table->unsignedInteger('ref_id');
$table->unsignedInteger('res_id');
$table->enum('gateway', ['idpay', 'zarinpal']);
$table->timestamps();
});
what is the problem?
Thanks in advance...
You should use belongsTo for the product relationship of OrderItem Model
OrderItem Model:
public function product() {
return $this->belongsTo(Product::class);
}
https://laravel.com/docs/8.x/eloquent-relationships#one-to-many-inverse
And hasMany for the order_items relationship of Product Model
Product Model:
public function order_items() {
return $this->hasMany(OrderItem::class);
}
https://laravel.com/docs/8.x/eloquent-relationships#one-to-many

Need to save foreign key manually on belongsTo relationship with withDefault()?

it seems that I need to save the original model on the newly generated model in order to save the relation correctly.
I hope the below test case illustrates my problem:
// migrations
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->bigInteger('user_id')->nullable();
$table->timestamps();
});
//models
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class)
->withDefault(['name' => 'Guest User']);
}
}
//test
public function test_foreign_key()
{
$post = factory(Post::class)->create();
$user = $post->user; // created from ->withDefault()
$user->save();
$this->assertNotNull($post->user);
$this->assertNotNull($post->user_id);
}
With additional association of the original model the test passes:
public function test_foreign_key_associates()
{
$post = factory(Post::class)->create();
$post->user->save();
$this->assertNotNull($post->user);
$post->user()->associate($post);
$this->assertNotNull($post->user_id);
}
edit: what I'm doing right now is the following for the withDefault relationship:
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class)
->withDefault(function (User $user, Post $post) {
$user->name = "Guest User";
$user->save();
$post->user_id = $user->id;
});
}
}

Get relationship data with laravel

I have 2 tables clients and maintenance_packages and I'm trying to list all clients and their maintenance package but keep getting the following error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'maintenance_packages.client_id' in 'where clause' (SQL: select * from `maintenance_packages` where `maintenance_packages`.`client_id` = 2 and `maintenance_packages`.`client_id` is not null limit 1)
I'm guessing it the way I've set up the relationships? Below is my DB Migrations, Models & Controller.
Clients DB
public function up()
{
Schema::create('clients', function(Blueprint $table) {
$table->increments('id');
$table->string('name', 55);
$table->string('email', 100);
$table->integer('maintenance_id')->unsigned();
});
}
Maintenance DB
public function up()
{
Schema::create('maintenance_packages', function(Blueprint $table) {
$table->increments('id');
$table->string('name', 55);
$table->integer('hours');
$table->decimal('price');
});
}
Client Model
namespace App;
use App\MaintenancePackage;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
protected $table = 'clients';
public $timestamps = false;
public function maintenance()
{
return $this->hasOne(MaintenancePackage::class);
}
}
Maintenance Model
namespace App;
use App\Client;
use Illuminate\Database\Eloquent\Model;
class MaintenancePackage extends Model
{
protected $table = 'maintenance_packages';
public $timestamps = false;
public function client()
{
return $this->belongsTo(Client::class);
}
}
Controller
public function index()
{
$clients = Client::with('maintenance')->get();
return view('clients.index', compact('clients', 'maintenance'));
}
Any help would be great.
In your Client Model replace
public function maintenance()
{
return $this->hasOne(MaintenancePackage::class);
}
with
public function maintenance()
{
return $this->BelongsTo(MaintenancePackage::class, 'maintenance_id');
}
Now In your Maintenance Model replace
public function client()
{
return $this->belongsTo(Client::class);
}
with
public function client()
{
return $this->hasOne(Client::class, 'maintenance_id');
}

Creating Simple Quiz Logic in Laravel

These are my Schema Tables
Schema::create('question', function(Blueprint $table) {
$table->increments('id');
$table->text('title');
$table->string('hint')->nullable();
$table->text('explanation')->nullable();
$table->string('referencematerial')->nullable();
$table->string('imagepath')->nullable();
$table->boolean('published')->default(1);
$table->timestamps();
$table->softDeletes();
});
Schema::create('answers', function(Blueprint $table) {
$table->increments('id');
$table->string('text');
$table->boolean('iscorrect')->nullable();
$table->timestamps();
});
Here is my Classes for Question and Answer.
class Answer extends Model
{
protected $table = 'answer';
public $timestamps = true;
protected $fillable = array('text', 'iscorrect');
public function Question()
{
return $this->belongsTo('Question');
}
}
class Question extends Model
{
protected $table = 'question';
public $timestamps = true;
protected $dates = ['deleted_at'];
protected $fillable = array('title', 'hint', 'explanation', 'referencematerial', 'imagepath', 'published');
public function Answer()
{
return $this->hasMany('Answer');
}
}
My QuizController
public function index()
{
$questions = Question::with('answers')->get();
return $questions;
}
BadMethodCallException in Builder.php line 2251:
Call to undefined method Illuminate\Database\Query\Builder::answers()
I have been trying to load the questions and answers on the page. It keeps giving me query builder error. Please feel free to chime into it.
The error is basically telling you that the relationship you have called (answers) doesn't exist.
You have called the relationship Answer() in your model but referenced it as answers in your query.
You either need to update the relationship in your model to answers() or change the query to $questions = Question::with('Answer')->get();
Update
Your relationship isn't calling the model correctly, it should be:
public function Answer()
{
return $this->hasMany('App\Answer');
}

Laravel: Eloquent Relationship error

I have a many to many relationship between products and a product_categories tables. Now I want to create a translation table for categories.
But how do I relate them in eloquent? i am learning database relationships so forgive my ignorance.
Here is my tables:
//languages
Schema::create('locales', function(Blueprint $table)
{
$table->increments('id');
$table->string('code', 2);
$table->string('name');
});
//products
Schema::create('products', function(Blueprint $table)
{
$table->increments('id');
$table->string('thumbnail');
$table->timestamps();
});
//categories
Schema::create('product_categories', function(Blueprint $table)
{
$table->increments('id');
$table->string('category');
});
//relationship table
Schema::create('product_productcategory', function(Blueprint $table)
{
$table->integer('product_id')->unsigned()->index(); // the id of the bear
$table->foreign('product_id')->references('id')->on('products');
$table->integer('product_category_id')->unsigned()->index(); // the id of the picnic that this bear is at
$table->foreign('product_category_id')->references('id')->on('product_categories');
});
//category translations
Schema::create('category_translations', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('product_categories')->onDelete('cascade');
$table->integer('locale_id')->unsigned();
$table->foreign('locale_id')->references('id')->on('locales')->onDelete('cascade');
$table->unique(['category_id', 'locale_id']);
});
Product Model:
class Product extends Model
{
protected $table = 'products';
public function product_category() {
return $this->belongsToMany('App\product_category', 'product_productcategory')->translation(1);
}
}
Product categories:
class product_category extends Model
{
protected $table = 'product_categories';
public function product() {
return $this->belongsToMany('App\Product', 'product_productcategory');
}
}
Category Translations
class Category_Translation extends Model
{
protected $table = 'category_translations';
public function product_category() {
return $this->belongsTo('App\product_category');
}
}
But when i run:
$product = App\Product::find(1)->first();
echo $product->product_category;
I get error:
Call to undefined method Illuminate\Database\Query\Builder::translation()
You should not call translation in the Product model category relation (because you still interacting with the query builder), instead you should access the translation as a property on the category object:
echo $product->product_category->first()->getTranslatedIn(1)->name;
So you could refactor your code like this:
Product Model:
class Product extends Model
{
protected $table = 'products';
public function product_category() {
return $this->belongsToMany('App\product_category', 'product_productcategory');
}
}
Product categories:
class product_category extends Model
{
protected $table = 'product_categories';
public function product() {
return $this->belongsToMany('App\Product', 'product_productcategory');
}
public function translations() {
return $this->hasMany('App\Category_Translation', 'category_translations');
}
// relation filtered by language (cannot be accessed as a property unless you define the parameter as optional)
public function translatedIn($language) {
return $this->hasOne('App\Category_Translation', 'category_id')->where('locale_id', $language);
}
// access translated object
public function getTranslatedIn($language) {
return $this->translatedIn($language)->getResults();
}
}

Resources