It's a many-to-many relationship. [Attachment] can be used for user's avatar or comment detail attachment image. table structure:
CommentDetail
id - integer
cid - integer
content - text
User
id - integer
name - string
Attachment
id - integer
key - string
AttachmentRelationship
id - integer
target_type - string ('user_avatar' or 'comment_detail')
target_id - integer (User -> id or CommentDetail -> cid)
attachment_key - string (Attachment -> key)
first, in AppServiceProvider, I had custom morphMap:
Relation::morphMap([
'comment_detail' => CommentDetail::class,
'user_avatar' => User::class,
]);
then in CommentDetail model, define attachment() method to get all attachments:
public function attachments()
{
return $this->morphToMany(
Attachment::class,
"target",
"attachment_relationships",
"target_id",
"attachment_key",
"cid",
"key"
);
}
now the problem comes. when I create a attachment through commentDetail like this:
$commentDetail = CommentDetail::findOrFail(4);
$attachment = $commentDetail->attachments()->create([
'key' => (string)\Uuid::uuid4(),
]);
it will create a [Attachment] record:
id key
10 968e22b8-e4fb-4743-bf08-8ac9cd8ecd56
and a [AttachmentRelationship] record:
id target_type target_id attachment_key
1 comment_detail 7 10
my question: why the [AttachmentRelationship] record 'attachment_key' field's value is not the [Attachment] record 'key' field's value = 968e22b8-e4fb-4743-bf08-8ac9cd8ecd56 (now it's 'id' field's value = 10) ?
Related
I am creating a new record for a table named services including some fields (name, department_id, description) in database. I need unique combination of pair two fields together (name and department_id). How can I validate it for creating and updating functions?
In ServiceRequest:
return [
'params.name' => 'required|unique:services,name and depatment_id',
];
In Service Model:
public function department()
{
return $this->belongsTo(Department::class);
}
In DepartmentModel:
public function services()
{
return $this->hasMany(Service::class);
}
In Route:
Route::apiResource('/services', ServiceController::class)->names([
'store' => 'services_store',
'update' => 'services_update',
]);
Forexample:
when there is a service in a specific department, it gives error!
if there is a record of name = service1 and department_id = 1, user cannot create same record combination of name and department_id again! user allow to create service with (name = service1 and department_id = another_number) or (department_id = 1 and name = another_name) but creating a new record with (name = service1 and department_id = 1) is not allowed
You can use the unique rule this way:
return [
'params.name' => [
'required',
Rule::unique('services', 'name')
->ignore($this->service)
->where('department_id', $this->input('params.department_id'))
],
];
Here you are telling Laravel to check if there is no existing record in the services table that have $this->input('params.name') as name and $this->input('params.department_id') as department_id.
The ->ignore($this->service) is here to make sure we ignore the current service (if we are updating), so it doesn't "find itself" during the validation.
$this->service will be the current instance you are updating (if you setup the routes and controllers correctly, which is another topic).
i have pivot table like this
this is my Users model
public function getHousing()
{
return $this->belongsToMany(Housing::class, 'user_housing', 'user_id', 'housing_id')->withPivot('primary');
}
this is my Housing model
public function getUser()
{
return $this->belongsToMany(Users::class, 'user_housing', 'housing_id', 'user_id')->withPivot('primary');
}
i want to save primary with 1, this is my controller
$getData = $this->crud->show($id);
if (!$getData) {
return redirect()->route('admin.' . $this->route . '.index');
}
$data = $this->validate($this->request, [
'housing_group_id' => 'required',
'housing_id' => 'required',
'primary' => 'required',
]);
$getData->housing_id = $getData->getHousing()->pluck('id')->toArray();
$getData->getHousing()->sync($this->request->get('housing_id'), ['primary' => 1]);
$id = $getData->id;
i already add array fill primary 1, but i have error like this
SQLSTATE[HY000]: General error: 1364 Field 'primary' doesn't have a default value
how to save additional field in pivot table laravel ?
thanks
in sync with additional column in pivot table, you should pass an associative array for each id with column name as key and field value as value
$elements_array[$this->request->get('housing_id')]=['primary' => 1]
$getData->getHousing()->sync(elements_array);
if you have more than an 'id' to sync ... you must repeat the first step for each id.
check this:
https://stackoverflow.com/a/27230803/10573560
I like to define Many To Many Polymorphic Relations like the one that is mentioned in laravel documentation, but with one difference that I like the primary key to be changed to slug. I do that in the model by protected $primaryKey = 'slug' but when I do that I can not retrieve relations anymore. I guess I must change the arguments of morphToMany and morphedByMany method to fix this. However, I don't know how should I do that.
I would appreciate your help.
posts
id - integer
name - string
slug - string (primary key)
videos
id - integer
name - string
tags
id - integer
name - string
taggables
tag_id - integer
taggable_id - integer
taggable_type - string
This is how it looks like.
// morphToMany($related, $name, $table = null, $foreignPivotKey = null,
$relatedPivotKey = null, $parentKey = null,
$relatedKey = null, $inverse = false)
So try this one in your Post model.
class Post extends Model
{
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable', null, null, 'taggable_id');
}
}
Hope this will help you.
Im creating a survey app, and basically when a user selects a input type of "select" it appears a option input that can be dynamiclly increase, but that im having some issues in inserting these options in my database, im sugin the sync method to insert these options in my table, but is giving me a error of
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'toufarto.question_id' doesn't exist (SQL: select `option_question_id` from `question_id` where `id` = 11)
Here is my code:
Tables:
questions:
- id;
- input_type;
option_question
- id;
- label_option;
- question_id
My controller:
public function store(Request $request)
{
$this->validate($request, array(
'label_option' => 'max:255',
'input_type' => 'required|integer'
));
$question = new Question();
$question->input_type = $request->input_type;
$question->save();
$question->options()->sync($request->option, false);
Session::flash('success', 'success');
return back();
}
My Question Model:
public function options()
{
return $this->belongsToMany(OptionQuestion::class,'question_id','id');
}
My OptionQuestion Model:
class OptionQuestion extends Model
{
protected $table = "option_question";
}
Note: How i could add the label column to the "sync" method, since i need to insert the label from the option field of the form
As mentioned in the docs of Laravel you need to define your parameters as follows:
$this->belongsToMany(Model,table_name);
or
$this->belongsToMany(Model, table_name, table_1_key, table_2_key);
Looking at your DB schematic however it seems you should make a small adjustment.
questions
- id
- input_type;
options
- id
- label_option
option_question
- id
- question_id
- option_id
Question model
public function options()
{
return $this->belongsToMany(OptionQuestion::class);
}
Options model
public function questions()
{
return $this->belongsToMany(Question::class);
}
In laravel we specify foreign keys this way
public function creator() {
return $this->belongsTo('App\Models\User', 'creator_id', 'id');
}
Is there some way to return dummy user ('system') when creator_id is null?
Reason: to display it in template.
For example:
If creator_id = 10 => creator = {id: 1, name: 'John'}
If creator_id = null => creator = {id: 0, name: 'system'}
Try this in your template :
{{ (model->creator) ? model->creator->name : 'system' }}
model will replace with your variable name.
Create a dummy user with id = 0 and name = 'System'.
Give the creator_id a default value of 0 in the migration