Get data from hasMany/belongsTo laravel elequent relations - php

I have two models products and image where product can have one or more image and image have one product related to and these are my models
product model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use OwenIt\Auditing\Contracts\Auditable;
use OwenIt\Auditing\Auditable as AuditableTrait;
class Product extends Model implements Auditable
{
use HasFactory, AuditableTrait;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'price',
'description'
];
/**
* Get all of the comments for the Product
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function images(): HasMany
{
return $this->hasMany(Image::class);
}
}
product migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->double('price');
$table->text('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
image model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Image extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'filename',
];
/**
* Get the user that owns the Image
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
}
image migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateImagesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('filename');
$table->bigInteger('product_id')->unsigned();
$table->timestamps();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('images');
}
}
i made a productController to manage data, but i don't get the full response i only get each table data not with the relation included in the response
I am using laravel 8x
edits
productController php
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return Product::with('images')->get();
}
}

In Product model:
public function image()
{
return $this->hasOne(Image::class, 'pro_id');
}
In Image model:
public function product()
{
return $this->belongsTo(product::class, 'pro_id');
}
In controller:
$img = product::find($id)->image->filename;
Make sure there is a record for the product in the image table. Otherwise you have to manage the errors.

Related

SQLSTATE[42P01]: Undefined table: 7

I'm newbiу in laravel 9. I just want create simple blog with the tables:users, stories,comments.I have next relationship
users->stories(One To Many, hasMany laravel) ,
stories->users(One To Many (Inverse) / Belongs To),
users->comments(One To Many, hasMany laravel) ,
comments->users(One To Many (Inverse) / Belongs To),
stories->comments(One To Many, hasMany laravel) ,
comments->stories(One To Many (Inverse) / Belongs To).
class User
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use App\Models\Story;
use App\Models\Comment;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function stories()
{
return $this->hasMany(Story::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Story:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Model\User;
use App\Model\Comment;
class Story extends Model
{
use HasFactory;
protected $fillable = ['description', 'textStory'];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Comment:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Story;
use App\Models\User;
class Comment extends Model
{
use HasFactory;
public function storyFunction()
{
return $this->belongsTo(Story::class);
}
public function userFunction()
{
return $this->belongsTo(User::class);
}
}
Stories migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('stories', function (Blueprint $table) {
$table->id();
$table->string('description');
$table->text('textStory');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('stories');
}
};
Comments migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('textComment');
//$table->foreignId('story_id')->constrained('stories')->onDelete('cascade');
/*$table->foreign('story_id')
->references('id')->on('stories')
->onDelete('cascade');*/
$table->timestamps();
});
Schema::table('comments', function(Blueprint $table) {
$table->foreignId('user_id')->constrained()->onDelete('cascade');
});
Schema::table('comments', function(Blueprint $table) {
$table->foreignId('story_id')->constrained()->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('comments');
}
};
But when i run php artisan migrate or php artisan migrate:refresh i see next error:
SQLSTATE[42P01]: Undefined table: 7 ?z?????С?s??: ??NВ????N??╡?????╡ "stories
" ???╡ N?N?NЙ?╡N?NВ??N??╡NВ (SQL: alter table "comments" add constraint "comment
s_story_id_foreign" foreign key ("story_id") references "stories" ("id") on dele
te cascade)
But if i delete or comment next strings in comments migration file:
Schema::table('comments', function(Blueprint $table) {
$table->foreignId('story_id')->constrained()->onDelete('cascade');
});
Migration run succesfull.
Please help me resolve this error.
Most likely, the table that Laravel finds using the conventions is missing. Specify the table explicitly as an argument to the constrained method like this Schema::table('comments', function(Blueprint $table) {
$table->foreignId('story_id')->constrained('Your_table_name')->onDelete('cascade');
});Foreign Key Constraints

Call to a member function attach() on boolean - Laravel

i have a problem with function attach(). I have created 3 tables. 1 table is for added movies. Table 2 applies to the movie categories. 3 table is a collection of movie ID and category ID. A combination of many to many.
When i want add a new video with category from form this i have error -> Call to a member function attach() on boolean. If anyone knows the answer, please help. Thank you for your time!
VideoController.php -> look at the method store();
<?php
namespace App\Http\Controllers;
use Request;
use App\Http\Requests\CreateVideoRequest;
use App\Video;
use App\Category;
use Auth;
use Session;
class VideoController extends Controller
{
public function __construct(){
$this->middleware('auth', ['except' => 'index']);
}
public function index(){
$videos = Video::latest()->get();
return view('videos.index')->with('videos', $videos);
}
public function show($id){
$video = Video::find($id);
return view('videos.show')->with('video', $video);
}
public function create(){
$categories = Category::pluck('name', 'id');
return view('videos.create')->with('categories',$categories);
}
public function store(CreateVideoRequest $request){
$video = new Video($request->all());
//dd($request->all());
Auth::user()->videos()->save($video);
$categoryIds = $request->input('CategoryList');
$video->categories()->attach($categoryIds);
Session::flash('video_created', 'Added');
return redirect('video');
}
public function edit($id){
$video = Video::findOrFail($id);
return view('videos.edit')->with('video', $video);
}
public function update($id, CreateVideoRequest $request){
$video = Video::findOrFail($id);
$video->update($request->all());
return redirect('video');
}
}
Video.php - model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
protected $fillable = [
'title',
'url',
'description'
];
public function user(){
return $this->belongsTo('App\User');
}
public function categories(){
return $this->belongsToMany('App\Video')->withTimestamps;
}
}
Category.php - model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $fillable = [ 'name' ];
public function videos(){
return $this->belongsToMany('App/Video')->withTimestamps;
}
}
User.php - model (maybe you need a User.php model solves problems)
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function videos(){
return $this->hasMany('App\Video');
}
}
Migration - create_category_video_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCategoryVideoTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('category_video', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('category_id');
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->unsignedBigInteger('video_id');
$table->foreign('video_id')->references('id')->on('videos')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('category_video');
}
}
Migration - create_categories_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
}
Migration - create_videos_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateVideosTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('videos', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('title');
$table->string('url');
$table->text('description');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('videos');
}
}
form.blade.php - simple form in Laravel Collection
{!! Form::select('CategoryList', $categories, null, ['multiple' => 'multiple']) !!}
For the timestamps for the pivot you would call the "method" withTimestamps() not a "property" named withTimestamps:
// Video
public function categories()
{
return $this->belongsToMany(Category::class)->withTimestamps();
}
// Category
public function videos()
{
return $this->belongsToMany(Video::class)->withTimestamps();
}

Eloquent relation query returning null value

I am trying to get some relational data. All the methods work well but only one method is not working. I am trying to call App\ModeltestMcqQuestion::find(id)->chapterwiseMcqs from tinker, but it is returning null. My database is well populated. I have tried with many id, but nothing is working.
My Models are:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class ChapterwiseMcq extends Model
{
use SoftDeletes;
protected $fillable = [
'topic_id',
'question_type',
'question',
'question_description',
'question_resource',
'a',
'b',
'c',
'd',
'answer',
'answer_description',
'answer_resource',
];
public function topic(){
return $this->belongsTo(Topic::class);
}
public function modeltestMcqAnswers(){
return $this->hasMany(ModeltestMcqAnswer::class);
}
public function modeltestMcqQuestions(){
return $this->hasMany(ModeltestMcqQuestion::class);
}
}
Another Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class ModeltestMcqQuestion extends Model
{
use SoftDeletes;
protected $fillable = [
'modeltest_question_set_id',
'chapterwise_mcq_id',
];
public function modeltestQuestionSet(){
return $this->belongsTo(ModeltestQuestionSet::class);
}
public function chapterwiseMcqs(){
return $this->belongsTo(ChapterwiseMcq::class);
}
}
Migrations:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateChapterwiseMCQSTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('chapterwise_mcqs', function (Blueprint $table) {
$table->id();
$table->foreignId('topic_id')->constrained()->onDelete('cascade')->onUpdate('cascade');
$table->integer('question_type');
$table->string('question');
$table->text('question_description')->nullable();
$table->string('question_resource')->nullable();
$table->string('a');
$table->string('b');
$table->string('c');
$table->string('d');
$table->string('answer');
$table->text('answer_description')->nullable();
$table->string('answer_resource')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('chapterwise_m_c_q_s');
}
}
Another migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateModeltestMcqQuestionsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('modeltest_mcq_questions', function (Blueprint $table) {
$table->id();
$table->foreignId('modeltest_question_set_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->foreignId('chapterwise_mcq_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('modeltest_mcq_questions');
}
}
All the relational queries work well except App\ModeltestMcqQuestion::find(id)->chapterwiseMcqs. Can anyone help me what is wrong with the code? Here, id represents id of the model.
I have found a solution. Defining the funtion name caused the problem, I think.
public function chapterwiseMcqs()
Thu function name should be chapterwiseMcq(), not chapterwiseMcqs(). Changing the name worked for me.

Problem with seeding data in pivot table in Laravel

I have a problem while attempting to seed my pivot table in database in Laravel. I get error
Base table or view not found: 1146 Table 'user_cuisines' doesn't exist
And my table name is actually user_cuisine, so it is like for some reason laravel doesn't show that table. I added in my relationships that user_cuisine is pivot table because of alphabet order. Any help is appreciated. Here is my code.
UserCuisineTableSeeder.php
<?php
use App\UserCuisine;
use App\UserProfile;
use Illuminate\Database\Seeder;
class UserCuisineTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$cuisines = UserCuisine::all();
UserProfile::all()->each(function ($userProfile) use ($cuisines) {
$userProfile->cuisines()->attach(
$cuisines->random(rand(1, 12))->pluck('id')->toArray()
);
});
}
}
DatabaseSeeder.php
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
$this->call(WhitelabelTableSeeder::class);
$this->call(CitiesTableSeeder::class);
$this->call(UserTableSeeder::class);
$this->call(UserProfilePropertiesSeeder::class);
$this->call(UserProfileTableSeeder::class);
$this->call(FieldTableSeeder::class);
$this->call(FieldValueTableSeeder::class);
$this->call(CuisineTableSeeder::class);
$this->call(LiteratureTableSeeder::class);
$this->call(MusicTableSeeder::class);
$this->call(SportTableSeeder::class);
$this->call(TvTableSeeder::class);
$this->call(UserCuisineTableSeeder::class);
$this->call(UserInterestTableSeeder::class);
}
}
UserCuisine.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserCuisine extends Model
{
protected $fillable = [
'name'
];
public function userProfiles()
{
return $this->belongsToMany(UserProfile::class, 'user_cuisine');
}
}
UserProfile.php
<?php
namespace App;
class UserProfile
{
public function user()
{
return $this->belongsTo(User::class);
}
public function cuisines()
{
return $this->belongsToMany(UserCuisine::class, 'user_cuisine');
}
}
user_cuisine_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUserCuisineTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('user_cuisine', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('cuisine_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('user_cuisine');
}
}
cuisine_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCuisineTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('cuisine', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('cuisine');
}
}
Laravel expect the table name to be user_cuisines but you named it user_cuisine without the "s"
You can fix that by changing your migration or adding protected $table = 'user_cuisine'; to your model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserCuisine extends Model
{
protected $table = 'user_cuisine';
}
As naming convention goes, I would recommend changing the table name 👍
Seems user_cuisines table does not exist, You have created cuisine not user_cuisines
Just put below code in UserCuisine model.
protected $table= 'user_cuisine';
I would recommend always use -m flag while creating a model to avoid these types of errors, for example.
php artisan make:model ModelName -m

Laravel 5.4 hasManyTrough 'Call to undefined method Illuminate\Database\Query\Builder::hasManyTrough()'

I am struggling to see, where I went wrong. It seams easy, I followed Laravel instructions https://laravel.com/docs/5.4/eloquent-relationships#has-many-through , but clearly I need someone more familar with this sort of code as whenever I try to fetch $stagingsystem-stagesubtype I get error
BadMethodCallException with message 'Call to undefined method >Illuminate\Database\Query\Builder::hasManyTrough()'
Can someone help?
StagingSystems
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateStagingSystemsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('staging_systems', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('staging_systems');
}
}
StageName
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateStageNamesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('stage_names', function (Blueprint $table) {
$table->increments('id');
$table->integer('staging_system_id')->unsigned();
$table->foreign('staging_system_id')->references('id')->on('staging_systems');
$table->string('name')->unique;
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('stage_names');
}
}
StageSubType
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateStageSubTypesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('stage_sub_types', function (Blueprint $table) {
$table->increments('id');
$table->integer('stage_name_id')->unsigned();
$table->foreign('stage_name_id')->references('id')->on('stage_names');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('stage_sub_types');
}
}
MODELS
StagingSystem
<?php
namespace App;
use App\StagingSystem;
use Illuminate\Database\Eloquent\Model;
class StagingSystem extends Model
{
protected $guarded = ['id'];
public function stagename()
{
return $this->hasMany('App\StageName');
}
public function stagesubtype()
{
return $this->hasManyTrough('App\StageSubType','App\StageName');
}
}
StageName
<?php
namespace App;
use App\StageName;
use Illuminate\Database\Eloquent\Model;
class StageName extends Model
{
protected $guarded = ['id'];
public function stagingsystem()
{
return $this->belongsTo('App\StagingSystem','id');
}
public function stagesubtype()
{
return $this->hasMany('App\StageSubType');
}
}
StageSubType
<?php
namespace App;
use App\StageSubType;
use Illuminate\Database\Eloquent\Model;
class StageSubType extends Model
{
protected $guarded = [
'id'
];
public function stagename()
{
return $this->belongsTo('App\StageName');
}
public function stagingsystem()
{
return $this->belongsTo('App\StagingSystem');
}
}
For anyone coming across this with a similar issue, this error message can appear if you are trying to access a models relationship using withPivot(), but the intermediate relationship extends Model instead of Pivot.
You have mistyped HasManyThrough as hasManyTrough.

Categories