I have table 3 tables, equipment(ID, name)
parameters(ID, name) and the pivot table equipment_parameter(equipment_id, parameter_id) , on my "Equipment" list view i need to add a column with the name of the parameter so i need to retrieve name from the Parameter table.
Equipment Model:
public function parametros(){
return $this->belongsToMany('App\Parametro','equipo_parametro','equipo_id',
'parametro_id')->withTimestamps();
}
Parameter model:
public function equipos(){
return $this->belongsToMany('App\Equipo','equipo_parametro','parametro_id',
'equipo_id')->withTimestamps();
}
i added this on equipmentCrudcontroller ,but have had no success.
$this->crud->addColumn([ // Select
'label' => 'Parametro',
'type' => 'select2',
'name' => 'equipo_id', // the db column for the foreign key
(not sure here since equipment foreign key is on pivot table????)
'entity' => 'parametros', // the method that defines the relationship in your Model
'attribute' => 'nombre', // foreign key attribute that is shown to user
'model' => "App\Parametro" // (doubt, there's a pivot table inbetween???) foreign key model
]);
If you are adding a column and have already run the previous migration you can create a new migration php artisan make:migration update_equipment_table inside of that, you can then do something like this
Schema::table('table', function (Blueprint $table) {
$table->string('column');
});
then rerun migrations php artisan migrate this will add the new column to your table.
Related
In the database I have columns: id, name, order, createdAt, updatedAt, createdBy, updateBy .
In controller : PostController.php
public function store(Request $request)
{
$req = Validator::make($request->all(), [
'name' => 'required',
'order' => 'required',
]);
if ($req->fails()) {
return response()->json(['error' => $req->errors()], 400);
}
$data = $request->all(); // name and order
Post::insert($item);
}
I want when I add data. Then createAt column and createBy column will be added. Instead of setting date('Y-m-d H:i:s) and $request->user()->id in controller, Then I want it to be placed in model, when i insert createAt and createBy columns are added. If it's update then I want the updatedAt and updatedBy columns to be added
You can add both createdAt and updatedAt in your migration file.
That will insert the current timestamp while inserting values into the table without adding them into the controller.
Please try like this while adding migration
Schema::create('table_name', function (Blueprint $table) {
$table->timestamp('createdAt');
$table->timestamp('updatedAt');
});
Instead of doing POST::insert($data); you could create/update a model more explicitly.
To add a new Post with only createdAt and createdBy you could do something like this:
$post = new Post;
$post->createdAt = $dateTime;
$post->createdBy = $userId;
$post->save();
Of course you can set any other attributes you are wanting to include before you save. And your updatedAt and updatedBy columns will have to be nullable in the database so that you don't get an error when you try to insert a record without including them.
Also as a note, Laravel has a feature that includes created_at and updated_at columns if you have: $table->timestamps(); included in your table's migration file. These fields will get automatically updated whenever a database entry is created/updated.
in your migration, you can just use the timestamps, it by default creates created_at and updated_at, and when you update an entry, Eloquent will update the value automatically for you, as for the created_by and updated_by, you can create them as well in migration, then setup an observer to set the values on create/update
ref: https://laravel.com/docs/8.x/eloquent#observers
I have two models:
Brands
Mods
I can display all brands via belongsTo function. Problem is when I try to save same brand two times, I get error duplicated entry.
This belongsTo is causing duplicated entry error when saving to DB two same brands.
Mods.php
public $belongsTo = [
'brand' => [\Slasher\Farming\Models\Brands::class, 'key' => 'id'],
];
This belongsToMany works, and save's data to DB, but is generating checkbox field (I only want to select one brand at one mod enty). I'm using pivot table for this relation.
Mods.php
public $belongsToMany =[
'brand' =>[
'Slasher\Farming\Models\Brands',
'table' => 'slasher_farming_mods_brands',
'order' => 'brand_name'
],
];
BelongsTo example: (Brands are visible and I can save them. But problem is when saving same brand for more than two times).
Error I get when saving with belongsTo.
I tried also creating inverse relationships on Brands model with (belongsTo and belongsToMany), but still getting this error.
What type of relation should I make, to save Brands as dropdown list and to fix this duplicate error?
If you're using a pivot table for your relation, then you should use $belongsToMany. Pivot table is only used for many-to-many relations.
I fixed this problem with changing column in the mods name brand to brand_id and also changing belongsTo relation. I just removed key, and it works like a charm. No need for pivot table here.
Mods.php
public $belongsTo = [
'brand' => ['Slasher\Farming\Models\Brands']
];
"SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '3' for key 'PRIMARY' (SQL: update liam_blog_blogs set id = 3, liam_blog_blogs.updated_at = 2022-07-26 09:30:09 where id = 2)"
When using the select2 field/column type in Laravel Backpack, the list view displays the 'id' of the foreign entity instead of the foreign key required (in this case the 'name' of the Session).
Laravel 5.8.4, Backpack 3.4. I asked in GitHub and the response was that my relationships were incorrect in my models. I don't think that's the problem as the name loads in the edit view.
GradeCrudController
$this->crud->addColumn([
'label' => "Session",
'type' => 'select2',
'name' => 'session_id', // the db column for the foreign key
'entity' => 'session', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'model' => "App\Models\Session" // foreign key model
]);
Grade (Model)
public function session()
{
return $this->belongsTo('App\Models\Session');
}
Session (Model)
public function grades()
{
return $this->hasMany('App\Models\Grade');
}
As it's been a few days and nobody has responded, I thought I'd post the answer I came up with. Note that I highly doubt that this is the correct solution, but for my project it will do.
I added a Laravel Observer for the Grade Model. Once a user adds a new record, the observer visits the session table, pulls the name of the session using the key and adds it as a column to the Grades table.
Then in backpack I just display the 'name' column.
There has to be a better way than this... But for now it will do.
I see you're using a "select2" column type. That's not something Backpack provides by default - it only has a "select" column.
Most likely what happened is that Backpack loaded the "text" column, since it couldn't find a "select2" column. Hence, the ID.
Try changing "select2" to "select". It should work for you without any observers/anything else.
I was having a similar issue. I could not get the foreign key attribute to show up no matter what. I finally got it working by doing to following.
Add the foreign key to the belongsTo method. It should be the name of the column in that model that has the ID that is associated with in the belongsTo model.
public function session()
{
return $this->belongsTo('App\Models\Session','name');
}
One other item that I suggest is to make sure all columns that have foreign keys are set to the same data types in the database.
I am trying to create a comment to a commentable model (which is created by using polymorphic relations.) using the morphname key.
For example; i would like create a comment giving the morph name (blog) and foreign_key (1). But the morph name could change. So we don't know which key can be with the request. I don't want to create actions for each resource.
AppServiceProvider:
Relation::morphMap([
'blog' => \App\Models\Blog\BlogPost::class,
'product' => \App\Models\Commerce\Product::class,
]);
Conroller -> action:
$this->validate($request, [
'commentable_model' => 'required|string',
'commentable_id' => 'required|integer|min:1',
'comment' => 'required|string'
]);
// i am trying to load data using morph name and foreign key here; but it's not working.
$model = $request->commentable_model::findOrFail($request->commentable_id);
$comment = new Comment;
$comment->comment = $request->comment;
$comment->commentable()->associate($model);
$comment->user()->associate(auth('api')->user());
$comment->save();
Commentable relation:
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->text('comment');
$table->integer('parent_id')->unsigned()->nullable();
$table->foreign('parent_id')->references('id')->on('comments')->onDelete('cascade');
$table->morphs('commentable');
$table->timestamps();
});
Data:
commentable_model => 'blog',
commentable_id => 1
I will send these data via api endpoints. So, i would like to use just morhpnames, not full class names.
I could not get it work.
Any ideas?
I found the solution and it was in front of my eyes all the time actually...
We are making the mapping using the Relation class.
I have checked if can we access the relations with any method or variables and the answer is yes.
The short answer is;
Relation::$morphMap
returns all the mapping as an array.
And my solution for the question is;
$model = Relation::$morphMap[$request->commentable_model]::findOrFail($request->commentable_id);
Accessing that array value using our given morph name (which is blog).
How can I define a many to many polymorphic relation with extra fields?
I have three (or more, as it is a polymorphic relation) tables.
tags table: id, name
tagged table: id, tag_id, taggable_id, taggable_type, user_id
posts table: id, record, timestamps
users table: id, name, email
The user_id on the tagged table referes to the users table on column id.
In my Post model I have:
public function tags()
{
return $this->morphToMany('App\Tag', 'taggable','tagged');
}
and in my Tag model I have:
public function posts()
{
return $this->morphedByMany('App\Post', 'taggable','tagged');
}
Then when I am try this in my controller:
$tag = new \App\Tag(
array(
'tag'=>"someTag"
));
$tag->save()
$post = \App\Post::find($id);
$post->tags()->save($tag);
I get Integrity Constraint Violation for not having a user_id:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (hb.tagged, CONSTRAINT tagged_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id)) (SQL: insert into tagged (tag_id, taggable_id, taggable_type) values (26, 2, App\Resource)).
Which is somewhat expected, as I have never had the chance to define or declare the user_id field.
Also, I have tried withPivot() on tags relation as follows, to no avail:
public function tags()
{
return $this->morphToMany('App\Tag', 'taggable','tagged')->withPivot('user_id');
}
Like in the comment: withPivot has nothing to do with saving/creating. If you want to pass additional pivot data when saving, do this:
$post->tags()->save($tag, ['user_id' => $userId]);