How to save In Pivot Table in Laravel - php

How to save data to pivot table in laravel , I have two tables has many-to-many relationship , so i create pivot table , I tried the sync() method to insert but it keep gives me this exception:
"message": "Call to a member function sync() on null",
"exception": "Symfony\Component\Debug\Exception\FatalThrowableError",
here is Contract Model :
class Contract extends Model
{
public function skills(){
$this->belongsToMany(RequiredSkills::class , 'contract_skills')->withTimestamps();
}
}
and here is RequiredSkills Model :
class RequiredSkills extends Model
{
public function contract(){
$this->belongsToMany(Contract::class , 'contract_skills');
}
}
and here is the controller :
class RequiredSkillsController extends Controller
{
public function store(Request $request){
$contract = new Contract();
$data = $request->all();
$requiredSkills = RequiredSkills::create([
'contract_id'=>$data['contract_id'],
'skills_tag'=>$data['skills_tag'],
'user_id'=>auth()->guard('api')->user()->id
]);
$contract->skills()->sync($requiredSkills->id);
return $requiredSkills;
}
}
how to solve the exception ?

You don't have to write data to the relationship table laravel does it for you
When using the 'sync ()' function Laraval will automatically record the relationship in the "contract_skills" table.
You are not writing Contract to the database so it has no ID, so you will not be able to link
Contract and Skills need to be recorded before you can call
the sync () function will execute the following insert:
insert into [contract_skills] ([contract_id], [skill_id]) values (1, 1)
I would do the store function as follows
class RequiredSkillsController extends Controller
{
public function store(Request $request){
//Create Contract in database
$contract = Contract::create($request->contract);
//Get skills id to link with contract
$data = $request->skills;
//syncs with additional data
$contract->skills()->sync(array_column($data, 'id'), ['user_id'=>auth()->guard('api')->user()->id]);
return $contract->refresh()->skills;
}
}

Related

Laravel 8 - I got this error 'SQLSTATE[42S02]' how can I solve this?

I'm trying to do follow system without any laravel libray. I got this error when I submit form. How can I fix it? I think error is about my user model and my follow model relationship but I couldn't solve.
My error is:
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'muzik.follows' doesn't exist (SQL: insert into follows
(following_id, follower_id, updated_at, created_at) values
(12, 30, 2021-04-02 22:32:50, 2021-04-02 22:32:50))
My User model contains the following relationship:
public function follows(){
return $this->hasMany('App\Models\Follow');
}
My User model contains the following relationship:
public function user(){
return $this->belongsTo('App\Models\User');
}
My controller is:
public function follow(Request $request){
$request->validate([
'follower_id'=>['required'],
'following_id'=>['required'],
]);
$follower_id = $request->follower_id;
$following_id = $request->following_id;
$save = Follow::create([
'following_id' => Auth::user()->id,
'follower_id' => $follower_id,
]);
if($save){
return back();
}else{
return back();
}
}
check your "Follow" model, you may needs specify table name with:
protected $table='tableWhereYouSaveFollows';
Did you check your migration I think you did not create the Follow table if you did try to Just specify your table in the model as such:
class follows extends Model{
public $table = "follow";
I think your follow table does not exist, first create your follow table and then add this to your follow model:
use Illuminate\Database\Eloquent\Model;
class Follow extends Model
{
protected $table="follows";
//---Guarded
protected $guarded = [];
//---User Function
public function user(){
return $this->belongsTo('App\Models\User');
}
}

Eloquent ORM dynamic table, creating via model fails to select table

On the REST API am building based on slim3, I use route parameters to dynamically select a tenant to do certain crud actions on.
The model:
class Customer extends Model {
protected $table = '';
protected $fillable = ['some', 'fields'];
public function setTable($table) {
$this->table = $table;
}
public function getTable() {
return $this->table;
}
}
Selecting and updating entries works (properly) like this:
// selects properly from $tableName table
$kd = new Customer;
$kd->setTable($tableName);
$data = $kd->whereEmail($args['email'])->firstOrFail();
Creation fails, using the same approach:
$kdc = new Customer;
$kdc->setTable($tableName); // it should use dbname.prefix_$tableName same as above
$kdc->create($customerData);
// fails with error Base table or view not found: 1146 Table 'dbname.prefix_' doesn't exist
I have checked that create() successfully calls getTable() from the Model and gets proper value. But it seems not to use it...

Laravel 5 push() not saving hasOne relationship

In my destroy function of my controller, I'm attempting to take a copy of my object (model with one relationship) and insert it into another database before deleting it. However only the model is being created and not the relationship. Why is this happening?
Destroy function:
public function destroy($id)
{
$user = User::with('Phone')->find($id);
$archive = $user->replicate();
$archive ->changeConnection('mysql2');
$archive ->push();
}
User model:
public function phone()
{
return $this->hasOne('App\Phone');
}
Phone model:
public function user()
{
return $this->belongsTo('App\User');
}
When I insert via the store function in my controller, it sets up the relationship just fine:
public function store(Request $request)
{
// Validation has passed, insert data into database
$user= User::create($request->all());
$user->Phone()->create($request->all());
}

Inserting two foreign keys to a pivot table after form submission using Laravel

I'm trying to create a resource provider database web app with a Resource, Location, ResourceLocation (pivot table), and ContactPerson models set up. I'm pretty sure I have the Model relationships set up correctly because from my Create A New Resource form it inserts the data into the database, it just doesn't show up in my view because the foreign keys (Resource_ID & Location_ID) aren't inserted into the pivot table. Here's the code I have so far.
Models
class Location extends Model
{
public function resource()
{
return $this->belongsToMany('App\Models\Resource', 'ResourceLocation');
}
}
class Resource extends Model
{
public function locations()
{
return $this->belongsToMany('App\Models\Location', 'ResourceLocation');
}
}
class ResourceLocation extends Model
{
protected $table = 'ResourceLocation';
public $timestamps = false;
protected $fillable = [
'Location_ID',
'Resource_ID'
];
}
Resource Controller
public function newResource(CreateNewResourceRequest $req)
{
$resource = Resource::create(Request::only(
'Name',
'Description',
'Misc_Info'
));
$location = Location::create(Request::only(
'Address',
'Address2',
'City',
'Zip_Code',
'County',
'Hours',
'Appt_Necessary'
));
$resource->save();
$resource->location()->attach($location);
\Session::flash('flash_message', 'Resource Created Successfully!');
return redirect('resource');
}
Once I hit the submit button on my form I get the error:
BadMethodCallException in Builder.php line 2345:
Call to undefined method Illuminate\Database\Query\Builder::location()
All the input from my form gets inserted into my database tables, but the ResourceLocation (pivot table) is left empty.
If I do $resource->$location()->attach($location['Location_ID']); it gives me a Method must be a string error. What am I doing wrong here? Any help would be greatly appreciated, thanks!
I figured it out, in my Resource Controller I have a location method:
public function location()
{
$locations = Location::all
return view (compact('locations'));
}
I changed my newResource method to:
public function newResource(CreateNewResourceRequest $req)
{
...
$resource->save();
$resource->locations()->attach($locations);
}

working on many to many table and more attributes are required in third table

i am trying to save data in third table in many to many relation but
data is not saving
user model
public function Jobs()
{
return $this->belongsToMany('App\Models\Job','App\Models\Job_User','user_id','job_id');
}
job model
public function Users()
{
return $this->belongsToMany('App\Models\User','App\Models\Job_User','job_id','user_id');
}
controller for saving data in third table is
public function JobApplied(Request $request){
$applied= new Job_User();
$applied->user_id = Auth::id();
$applied->job_id = $request->job_id;
$applied->cv = $request->cv;
$applied->current_salary = $request->current_salary;
$applied->expected_salary = $request->expected_salary;
$applied->save();
return redirect('searchjobs');
}
code of third table is
class Job_User extends Model
{
protected $fillable = [
'user_id','job_id','cv','current_salary','expected_salary','status',
];
protected $table = 'jobs_users';
}
You're using the many-to-many relation incorrectly. You don't need a model for the intermediate table as Eloquent will handle it for you.
First of all, you need to define the relation in your models in a correct way. The second argument should be the name of the intermediate table, not the model. As you're using the default values for table name and foreign key column names, you can skip them and just do:
public function Jobs()
{
return $this->belongsToMany('App\Models\Job');
}
public function Users()
{
return $this->belongsToMany('App\Models\User');
}
If you want to have additional fields in the intermediate column, you need to define it when you define a relationship using withPivot() method:
public function Jobs()
{
return $this->belongsToMany('App\Models\Job')->withPivot('cv','current_salary','expected_salary','status');
}
public function Users()
{
return $this->belongsToMany('App\Models\User')->withPivot('cv','current_salary','expected_salary','status');
}
Now, if you want to link a Job with a User and set the fields in the intermediate pivot table, you should use save() method on your relation:
$job->users()->save($user, ['cv' => $request->cv, 'current_salary' => $request->current_salary]);
or
$user->jobs()->save($job, ['cv' => $request->cv, 'current_salary' => $request->current_salary]);
Once you have data saved in your database you can retrieve data from intermediate pivot table using the pivot attribute of related model, e.g.:
foreach($user->jobs as $job) {
echo $job->pivot->current_salary;
}
or
foreach($job->users as $user) {
echo $user->pivot->current_salary;
}
Check the docs for more information about handling many-to-many relationship with Eloquent: https://laravel.com/docs/5.1/eloquent-relationships#many-to-many

Categories