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
Related
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.
I'm working on team management project.
I have a problem with doing relationships.
I want to display users in boards, but also want to look good and easy to read. I already designed relationships but when I saw JSON output of relationships, it was completely messed.
Is there some way how to display relationship data this way?
{
"id": 1,
"name: "Test",
"members": [
{
... user model here
"name": "Peter",
"email": "peter#peter.com",
}
]
}
My migrations:
Boards migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBoardsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('boards', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('boards');
}
}
Membership migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMembershipsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('memberships', function (Blueprint $table) {
$table->increments('id');
$table->integer('board_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('memberships');
}
}
EDIT:
Models
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Board extends Model
{
protected $fillable = ['name'];
public function members() {
return $this->hasMany(Membership::class)->with('user');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Membership extends Model
{
protected $fillable = ['board_id', 'user_id'];
protected $hidden = ['created_at', 'updated_at'];
public function user() {
return $this->hasOne(User::class, 'id', 'user_id');
}
}
You can try to define the relationships in the models as a Many to Many one, i.e.:
class User
{
public function boards()
{
return $this->belongsToMany('App\Board', 'memberships', 'user_id', 'board_id');
}
}
class Board
{
public function members()
{
return $this->belongsToMany('App\User', 'memberships', 'board_id', 'user_id');
}
}
With that relations defined you don't really need a Membership Model if it has not additional fields, and you can write code like that:
User::find($id)->boards
Board::find($id)->members
Board::with('members')->find($id)
You could read also the documentation on Many to Many Relationships
I am building a multi authentication system using laravel 5.5. I have Admin and AdminRole Models as well as they respective migrations.There is one to one relationship between the Admin and AdminRole Models. Everything works fine. But when i tried to access the admin_role like so:
$admin->adminRole->name; It throws an error like so:
Illuminate/Database/QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'admin_roles.admin_id' in 'where clause' (SQL: select * from admin_roles where admin_roles.admin_id = 1 and admin_roles.admin_id is not null limit 1)'.
I have tried for many hours but could not be able to figure out what the problem is. Any help will be greatly appreciated. Thanks in advance.
Admin.php Model:
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
use Notifiable;
protected $guard = 'admin';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'ip_address',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function adminRole() {
return $this->belongsTo('App\Models\AdminRole');
}
}
admins.php migrations
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAdminsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->increments('id');
$table->integer('admin_role_id')->unsigned()->nullable();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->ipAddress('ip_address')->nullable();
$table->string('photo')->default('avatar.png');
$table->boolean('status')->default(true);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('admins');
}
}
AdminRole.php Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class AdminRole extends Model
{
//
protected $fillable = ['name'];
public function admin()
{
return $this->hasOne('App\Models\Admin');
}
}
admin_role.php migrations
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAdminRolesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('admin_roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('admin_roles');
}
}
The code was actually correct, i cleared my cache and reboot my system. It is working now. Thank you guys.
https://imgur.com/a/ob9rjIz
There are two tables one called user and another called user_relation_user
My relation is an user to many user_relation_user and in my migration. I want to create 10 user with php artisan tinker so i run factory(App\User::class, 10)->create(); at the end i access to my database so do select * from users there are 10 users but in user_relation_user isn't 10 id or it's empty
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Administrator extends Model
{
protected $table = 'user_relation_user';
protected $primaryKey = 'id';
protected $fillable = ['user_id'];
public function users(){
return $this->belongsTo(User::class,'user_id');
}
}
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
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',
];
public function administrator(){
return $this->hasMany(Administrator::class,'user_id');
}
}
//hasMany
My migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUserRelationUserTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('user_relation_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('user_id_admin')->unsigned();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*foreign
* #return void
*/
public function down()
{
Schema::dropIfExists('user_relation_user');
}
}
The relation you define is correct,you just need to define a relation in user model as well.
Example:
Suppose you are developing a blog system where user can post blogs.
then there will be two models user model and blog model
In User model you have to define user relation as below:
public function blogs()
{
return $this->hasmany(Blog::class);
}
Then in blogs model
public function users()
{
return $this->belongsTo(User::class);
}
The product data always return null when i get the incoming_goods data (belongsTo).
Here is my Product Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Product extends Model
{
use SoftDeletes;
protected $guarded = [
'id', 'created_at', 'updated_at', 'deleted_at',
];
public function transaction_details()
{
return $this->hasMany('App\Transaction_detail');
}
public function incoming_goods()
{
return $this->hasMany('App\Incoming_good');
}
}
Here is my Incoming_good Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Incoming_good extends Model
{
protected $guarded = [
'id', 'created_at', 'updated_at',
];
public function product()
{
return $this->belongsTo('App\Product');
}
}
And here is my migration of that two table:
products table Migration:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 50);
$table->integer('price');
$table->integer('stock')->nullable();
$table->integer('available');
$table->string('image1', 190)->nullable();
$table->string('image2', 190)->nullable();
$table->string('image3', 190)->nullable();
$table->string('image4', 190)->nullable();
$table->string('image5', 190)->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
incoming_goods migration:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTableIncomingGoods extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('incoming_goods', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id');
$table->integer('stock');
$table->text('note')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('incoming_goods');
}
}
Here is my code to show incomong_goods data and product (relation belongsTo):
$data = Incoming_good::select('id', 'stock', 'note', 'created_at')->with('product')->get();
I've try to use alies, but still it return the product data null. Hope you can help me :)
In order to match up the eager loaded Products with the Incoming_goods, Laravel needs the foreign key to be selected. Since you did not include the foreign key (product_id) in the select list, Laravel can't match up the related records after retrieving them. So, all your product relationships will be empty. Add in the foreign key to the select list, and you should be good.
$data = Incoming_good::select('id', 'product_id', 'stock', 'note', 'created_at')
->with('product')
->get();