I have a laravel project working fine but i can't see relationship in sql server.(for which i am using xampp).
I expect the foreign-id in laravel is the foreign id in actual table. It is working fine in laravel, i expect it to work in actual database server also.
This is my model, Student Model and migration:
public function user() {
return $this->belongsTo(User::class);
}
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string("username")->unique();
$table->foreignId("user_id");
$table->foreignId("course_id");
$table->bigInteger("class_roll");
$table->integer("year");
$table->integer("semester")->nullable();
$table->timestamps();
});
User Model and migration:
public function student()
{
return $this->hasOne(Student::class);
}
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->boolean('is_active');
$table->enum('role', ['admin','instructor','student']);
$table->string("fullname");
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
In designer view, there is no link between students.user_id, and users.id:
There are many better guides out there that explains this, so I will try to keep this simple, there are 2 things you need to understand about how database relationships work within laravel:
1- You can connect your database tables to be related to each other, this has many benefits where you can cascade delete data as an example.
You are currently not telling mysql which tables are being connected, you can see a better way to do this from the following stackoverflow: laravel migration best way to add foreign key
2- You can connect your database tables using Models, this will not show up anywhere in MYSQL designer, because this is mainly code base, which is enough to handle all of the data processing between relationships.
This part you already did.
Related
I want to create the migrations file in dynamic. I developed a product management system and there are multiple stores in the system. I want to create product tables for the store when registering the store.
my table names should like
store1_products
store2_products
store3_products
table structure are same
want to create these migration files in store create function
I all ready tried schema function on controller .
Schema::create($tableName, function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamps();
});
It created the table on the database but I want to create the migration file too
I suggest to just create a one table for the store and one table for the product. Then the product table must have a column that identify what store it is belongs to.
Stores Table.
Schema::create('stores', function(Blueprint $table) {
$table->id();
$table->string('store_name');
$table->timestamps();
});
Products Table
Schema::create('products', function(Blueprint $table) {
$table->id();
$table->string('product_name')->unique();
$table->unsignedFloat('price');
$table->unsignedTinyInteger('quantity');
$table->foreignId('store_id')
->constrained('stores')
->cascadeOnDelete();
$table->timestamps();
});
Then you can refer to Laravel Eloquent Relationship to know how to define their relationship.
Just make sure that you have model for them
I am confused about Laravel database relationship (unsigned id, foreign references, cascade).
Do I have to use relationship in class (like hasMany, hasOne) and in table migration (like foreign, references); for both of them too?
I had read some articles but they are not clear for me. what is the best way for best developing on an example?
As an example for category and blog post; how should it be or your best example please?
create_categories_table migration:
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
}
create_posts_table migration:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug');
$table->longText('description');
$table->timestamps();
});
}
and Post Model:
public function category()
{
return $this->belongsTo(Category::class);
}
thank you.
Technically you don't have to define relationships between related data in your database, however, it is good practice to do so and provides benefits such as data integrity and cascading. There are also tools that can reverse engineer your database to generate a visual representation of its structure including relationships if they have been defined.
Adding relationships in your migration files creates that relationship at the database level, informing the engine that there is a logical relationship between data. You can define a foreign key constraint in your migrations in many ways, however, as of Laravel 7.x there is a forieignId method and a constrained method providing a simplified way of defining relationships from the previous method.
So for a basic example, to define a simple one-to-one relationship you might do:
public function up()
{
Schema::create('child', function (Blueprint $table) {
$table->foreignId('parent_id')->constrained();
});
}
Similarly, using Eloquent relationships to define relationships at the application level is not required. However, these helper methods provide a consistent and simplified implementation for managing related data that would otherwise require you to write additional code.
At least one but ideally both of the above would be used.
Update
if we need set a foreign key as a different key the using is just like
->constrained('privateName_categories'). two basic questions: * how Laravel understands that the reference table is 'categories' on your
example without writing its name?
The argument provided to constrained is not the name of the foreign key field but the name of the table the foreign key references. This is used in instances that either your foreign key or the table it references differ from the standard Laravel naming conventions and therefore cannot be inferred.
Laravel uses naming conventions to make connections between things. For foreign keys that convention has the format {table}_{id}. Laravel inspects the foreign key name and then uses the {table} element of the convention to create the relationship behind the scenes. If you're not using conventions you need to inform Laravel.
The following uses conventions to automatically create a relationship between the posts and categories table based on the value of the foreignId method argument.
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->foreignId('category_id')->constrained();
});
}
This example doesn't use a standard foreign key naming convention and so the related table needs to be provided to constrained.
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->foreignId('another_field')->constrained('categories');
});
}
Similarly, for scenarios in that you're not using conventions, you might need to specify the related column names in your Eloquent Model relationship. The exact syntax for this differs based on the type of relationship (hasOne, hasMany, manyToMany, etc.). You can read up on the different syntaxes for each relationship in Laravels defining relationships documentation.
you mention about reverse engineering tools
DataGrip by JetBrains can inspect the schema of your database and produce a visual representation. Others are also available, just do a search of the internet.
The role of migrations is to build your database schema (INSERT TABLE, ALTER TABLE, FOREIGN KEYS, DROP COLUMN, etc...).
The role of relations in Eloquent Model is to make Model aware of relations with other models. It provides a convenient way to query related models.
Relations will not create foreign keys for you.
For example if a post can be in only one category and a category contains many posts :
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
}
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('category_id');
$table->string('title');
$table->string('slug');
$table->longText('description');
$table->timestamps();
$table->foreign('category_id')->references('id')->on('categories');
});
}
Then, in your Post model :
public function category()
{
return $this->belongsTo(Category::class);
}
If you need you can also add this to Category Model :
public function posts()
{
return $this->hasMany(Post::class);
}
This will allow you to easily retrieve all posts of a category for example :
public function getPostsByCategory(int $categoryId)
{
$posts = Category::find($categoryId)->posts()->get();
return $posts;
}
EDIT :
I think the main interest is when you want to eager load relations.
For example you have posts in a blog.
Each post have many categories. (a post can be in many categories).
Each category have many posts.
Each post have many comments
In homepage I want to display last 5 posts with for each post their categories and comments.
If I build well designed relations, I can do this:
public function getLatestPosts()
{
return Post::query()
->with(['categories', 'comments'])
->orderBy('created_at', 'desc')
->limit(5)
->get();
}
It will get last 5 posts and it will attach categories and comments to each Post model.
Friends I have the following problem with laravel migrations using postgres, and when I make changes to a migration, in this case the users table, but I get an error trying to remove an index from a key, can you help me please with this problem.
This is my migration code:
public function up() {
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->integer('idProfile');
$table->string('name');
$table->string('surname');
$table->string('email')->unique();
$table->string('photo')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function down() {
Schema::dropIfExists('users');
Schema::table('users', function (Blueprint $table){
$table->dropPrimary('id');
$table->dropIndex('users_pkey');
});
}
response from my console:
These are the indices that list me:
This is the structure of the final table:
Comments, things to improve I am all ears
When you are running migrate:refresh, you are running the down method. In your down method, you are dropping the table, and then trying to make edits to it, which is why you are getting "users" doesn't exist.
If this is just in a development env, make your changes in the up method, and remove everything apart from dropIFExists() from the down method.
It is highly recommended that don't change the migration file...
If you need to add a new row to your table (Consider you have mytable and you want to add myrow to the table), you can write in terminal :
php artisan make:migration add_myrow_to_mytable_table
after that , edit new added migration file!
remember to add the following code in down function :
Schema::table('mytable', function (Blueprint $table) {
$table->dropColumn('myrow');
});
after all, run :
php artisan migrate
If you want to remove a column from your table just follow this one :
Laravel Migrations - Dropping columns
The weekends table will be created first so I am thinking an weekendsteam_id needs to be in weekends and do a select statement. But I am getting really confused. Basically the user will enter a weekend. Then on a different view they will enter the team for that weekend. I need to find a way to tie the two tables together so I can query it for the weekend view on the front end.
Weekends Table
Schema::create('weekends', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->mediumText('verse');
$table->string('songtitle');
$table->string('songvideo');
$table->string('image')->default('default.png');
$table->string('videolink')->nullable();
$table->timestamps();
});
Weekends Team
Schema::create('weekendteam', function (Blueprint $table) {
$table->id();
$table->string('firstname');
$table->string('lastname');
$table->string('position');
$table->timestamps();
});
This sounds like a good use for a one-to-many relationship. Since it looks like you are storing the team members and their positions in the weekendteam table, you can simply add a weekend_id column (I also renamed the table to weekend_team_members):
Schema::create('weekend_team_members', function (Blueprint $table) {
$table->id();
$table->foreignId('weekend_id');
$table->string('firstname');
$table->string('lastname');
$table->string('position');
$table->timestamps();
});
Then, in order to get the team for any weekend, you can use a query like this:
SELECT * FROM weekend_team_members WHERE weekend_id = 1;
Which will fetch all of the team members for the weekend with that ID. If you are using Eloquent models, you can also use their built-in relationships to make querying easier:
class Weekend extends Model {
...
public function weekendTeamMembers() {
return $this->hasMany(WeekendTeamMember::class);
}
}
class WeekendTeamMember extends Model {
...
public function weekend() {
return $this->belongsTo(Weekend::class);
}
}
Once these relationships are defined in the models, you can use them to help you query the data. For example, if you already have a Weekend in the variable $weekend, you can fetch all of the team members like this:
$teams = $weekend->weekendTeamMembers;
Or, if you have a team member, you can get the weekend like this:
$weekendTeamMember->weekend;
I tried to follow the documentation of laravel and laracasts, however I get an error in my migrations concerning foreign keys.
I have articles about games that are written by authors (users), so I want the user Id for the article.
This is my games table:
public function up()
{
Schema::create('games', function (Blueprint $table) {
$table->id('id');
$table->timestamps();
$table->string('name', 100);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->text('description');
$table->string('publisher');
$table->string('url');
});
}
And this my user table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
If I understand correct I name the column in the games table 'user_id', and it references to the Id of the user, which is called 'id' in the user table?
When migrating however i get the error theres no user_id.
SQLSTATE[42000]: Syntax error or access violation: 1072 Key column 'user_id' doesn't exist in table (SQL: alter table gamesadd constraintgames_user_id_foreign foreign key (user_id) references users (id) on delete cascade)
Can someone tell me what I am doing wrong? Am I mixing up where I should refer to 'id' in the user table?
Migrations by default are run with the same order that they are been created, and in your case, the games migration is been executed before the user migration, and so you when migrating the games migration, there is no user table, and so
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Will fail.
In order to solve this problem, rename the user migration with a date before the one that has the games migration
Thanks to #lagbox for having pointed it out:
This line is not creating a new field, but is just adding a constrain
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Instead you should first create the field and then create the constrain:
$table->bigInteger('user_id)->...;
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
The way I usually do it is :
Creating the migrations files (containing all the fields)
Creating alterations files (adding FK)
Like that, when I run php artisan migrate the order of the migrations doesn't block anything.
With your code above you are trying to add a foreign constraint on a field which doesn't exist yet