How to populate pivot table with fake data in laravel? - php

I use factory and seeder in laravel to insert fake data in my tables with my models to test its efficiency, now I have a pivot table post_tag that has post_id and tag_id,
how can I insert fake data in the pivot table.Should I make a model named Post_Tag?
I think this way it's not true...
Thanks

You should create a model called Post_Tag. Every model is associated with a table from your DB. After creating the model you should create the seed file.
Of course you could just create the model and insert a new line in your PostSeeder file but it's nice to have things organized.

Related

Laravel Eloquent Model can't sync with pivot data in Many-to-Many relationship

I would like to sync the data instead of attach the data to the particular relationship.
Pivot relation UserModel code
public function carts(){
return $this->belongsToMany(Product::class,'user_carts')->withPivot('quantity');
}
The attach code is
User::find(1)->carts()->attach($s,["quantity"=>1]);
The sync code is
User::find(1)->carts()->sync($s,["quantity"=>1]);
When I try to compile the sync, those pivot relation that matched user_id = 1 does not have the "1" in its respective quantity column.
If I would like to achieve the sync function without using attach, how can I do it because the attach() will create multiple redundant data in my database.
You have to pass key values in the sync method.
Assuming $s is the id (key) to be synced:
User::find(1)->carts()->sync([$s => ["quantity"=>1]]);

laravel models fill additional field inside many-to-many table

I am a newbie at Laravel framework and trying to work me in.
I already understand how to generate N:M relationships and handle them inside the models. Now I am asking you how to fill an additional field inside the many to many tables?
For example:
Table Foo
Table User_Foo
user_id
foo_id
is_owner (bool)
Table User
Now I want to declare which of the foo users is the real owner.
In my opinion, the N:M Table has stored this information an not the Foo itself.
So how is it possible to declare those additional fields inside of my Foo and User model?
Retrieve additional fields you can with withPivot() method
return $this->belongsToMany('App\User')->withPivot('is_owner');
Fill you can with sync() or attach() methods.
Laravel relations doc
Laravel provides us with concept of pivotwhen defining N-M relationships. By default the table will have the both connected keys. But if you want to add extra fields in that bridge table.
$model->belongsToMany('Model')->withPivot('column1', 'column2');
In above case, your pivot table will have two additional columns and you can access these columns as:
$model->pivot->column1
$model->pivot->column2

L5.5 relationship of pivot table with another model

In my application, a model Device has a many-to-many relationship with model Task.
A combination of Device and Task could be assigned to a various number of model User.
example: Device A has a Task Check something and this should be done by User Frank and Steven.
From my point of view, this should be a "standard problem", but so far I could not find a proper solution.
Right now, I use following workaround:
a) added an unique ID id to the device_task pivot table
b) query id from the pivot table
c) create a new table device_task_user which contains user_id and device_task_id
b) use query builder to get/add users
But I am really not happy with this approche.
Would it be possible, that the pivot table also extends Model and then have a one-to-many relationship with User?
Or would you suggest to add a json colum to the pivot table and store the users there?
Any idea would be very welcome!
Would it be possible, that the pivot table also extends Model
Yes, it's possible. From the docs:
If you would like to define a custom model to represent the intermediate table of your relationship, you may call the using method when defining the relationship. All custom models used to represent intermediate tables of relationships must extend the Illuminate\Database\Eloquent\Relations\Pivot class
You also can create a new hasMany() and belongsTo() relationships between Task and Device models and use them as well as existing belongsToMany relationship. And you'll need to define a new relationship between pivot model and User model to be able to get data by device, task or user.
Modify many-to-many relationship to hold an extra field user_id
class Device extends Model
{
public function tasks()
{
return $this->belongsToMany(
Task::class,
'device_task',
'device_id',
'task_id'
)->withPivot('user_id');
}
}
And when updating do like this in controller
$device->tasks()->attach([$taskId]=>['user_id']=>$userId);
And of-course you need DeviceTask model and also a has-many relationship between User model and DeviceTask model to get user's task

Why the name convention of Laravel relationships so weird?

I have three tables:
users
columns: id, name
books
columns: id, name
book_user:
columns: user_id, book_id, state(not read yet, reading, read already)
I intended to user book_user as many-to-many relation table, so I follow the name convention from doc:
To define this relationship, three database tables are needed: users, roles, and role_user. The role_user table is derived from the alphabetical order of the related model names, and contains the user_id and role_id columns.
I wrote code:
class User extends Model
{
public function books()
{
return $this->belongsToMany('App\Book');
}
}
, and I can retrieve the books which related to the user by call user->books().
That works well, but when I try to retrieve the state of the book which related to a user, I create model:
class BookUser extends Model
{
//
}
When I use this Model, it claims:
Base table or view not found: 1146 Table 'myapp.book_users' doesn't exist
Conclusion:
the name convention of a table which can be used as many-to-many is <singular_noun>_<singular_noun> (such as book_user).
the name convention of table with multiple words which mapping to a Model is <singular_noun>_<plural_noun> (such as book_users).
I know I can set the table name manually which a model mappings to, but I just wonder:
Does that conflict is a design flaw or just I'm doing wrong in designing tables and models?
You don't need define a model for pivot table,just add withPivot
class User extends Model
{
public function books()
{
return $this->belongsToMany('App\Book')->withPivot('state');
}
}
Then you can retrieve book states from model pivot
Generally you don't need a model for pivot tables. You can define the inverse of the relationship. And if you want to store extra data in pivot table maybe you can check withPivot method. Or explain what are you trying to do.
But if you want to create a model, you need to specify your table name in your model manually. Because Laravel doesn't know if its a pivot table or normal table. It just tries to guess the table name by making it plural.

What is the right Laravel class name for a given table name?

If I have database table suggestions_votes, what would be the correct name of Laravel (5.1) Class (SuggestionsVote or SuggestionVote)?
Table was created by migration, using
Schema::create('suggestions_votes', ...
Laravel recommends certain conventions, but they also provide you with options to override them.
If your model is "SuggestionVote", then the table associated with that model will be the snake case plural name of the class. In other words, it would look for the table "suggestion_votes". If you want to override the associated table name, you can add this property to your model:
protected $table = 'suggestions_votes';
If you are actually creating a pivot table for the models "Suggestion" and "Vote", then Laravel will by convention join the two related model names in alphabetical order. In other words, it will look for the pivot table "suggestion_vote". You can override this though when you define the relationship. For example:
return $this->belongsToMany('App\Suggestion', 'suggestions_votes');
Where 'App\Suggestion' would be fully namespaced path to your Suggestion class.
It depends. You can make any name work.
If you have no control of the database, the model 'should' be SuggestionsVote
If you do have control over the database, I would rename the table to suggestion_votes and the model name would be SuggestionVote

Categories