Add records to pivot table - laravel

i have 3 tables.
table users
id
name
table identifiers
id
email
and pivot table identifier_user
identifier_id
user_id
when store data I when to add data to the pivot table, example :
$user=new User ;
$iden=new Identifier ;
I use $user->identifiers()->attach($user->id) , but the one just add the data to identifier_id but i want to add data to user_id to
NB: I made the relationship ManeytoManey in the two models

First of all: you cannot do your task like in question, cause $user = new User; only creates default User class instance.
For example: if you doesn't have a user, you need to create it like this:
$user = User::create($userData);
But if you already has user in database:
$user = User::findOrFail($userId); or $user = User::where(['some_field' => $some_value])->first();
After that, you can attach relation:
$user->identifiers()->attach([$identifier_ids]);
if you already know relation ids, or, if you need to create it:
$user->identifiers()->([
new Identifier($identifierDataArray),
new Identifier($identifierDataArray),
]);
Hope it helps you.

Related

Laravel Many to many relationship with custom key relation

Before you mark this question as duplicate, please see the details :) I have a problem related to many to many relationship with custom columns linking
I have following tables
Employees
-Id
-brink_id <----- This is third party id I am saving of employee
-name
Jobs
-id
-brink_id <----- This is third party id I am saving of job
-description
employee_job
-id
-brink_id <----- This is third party id I am saving of relationship for third party
-brink_employee_id
-brink_job_id
In Employee Model I have created relationship
public function jobs()
{
return $this->belongsToMany('App\Models\Job','employee_job','brink_employee_id','brink_job_id');
}
And in Jobs Model
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function employees()
{
return $this->belongsToMany('App\Models\Employee','employee_job','brink_job_id','brink_employee_id');
}
Actually I want to have many to many relationship with brink_id in employees table and brink_id in jobs table presented as brink_employee_id, brink_job_id in employee_job table not with ID (primary columns of respective table).
But when I try to insert in pivot table using following, it always inserts employee ID rather than brink_id
$employee = Employee::with('jobs')->where('brink_id',$employeeJob['brink_employee_id'])->first();
$employee->jobs()->attach($employeeJob['brink_job_id'], ['is_active' => 1]);
For example if brink_id in employee table is 123456 and ID is 1, the above code in employee_table will store 1 in employee_brink_id rather than 123456.
Please let me know what I am doing wrong.
If you don't specify a different parent key and related key, it will default to your current model's primary key and the related model's primary key respectively.
Specify the parent key name as the 5th argument and the related key name as the 6th argument:
return $this->belongsToMany('App\Models\Employee', 'employee_job', 'brink_job_id', 'brink_employee_id', 'brink_id', 'brink_id');
However, I'd personally use the ids from your system and not the ids from a 3rd party system in your relationships.

Get back data from the pivot table when store a many-to-many relationship

I have a many-to-many relationship between projects and surveys. I can successfully create a relationship between a survey and a project with
$userSurvey = $project->surveys()->save($survey);.
This will create a new record inside the question_survey pivot table (The pivot table contains the columns id, question_id and survey_id.)
$userSurvey will receive the newly created survey model. Is there any way to receive also the id of the new record in the question_survey pivot table?
When retrieving many to many relationships, Laravel will automatically attach the pivot to the resulting Model, so in your case, $userSurvey will automatically have an attribute called pivot that holds, well, of course, the pivot.
But by default, that pivot attribute only holds the foreign keys, so in your case, the question_id and survey_id. If you have any other extra attributes,(in your case id), simply use the withPivot method, as follows.
public function surveys()
{
return $this->belongsToMany('App\Question', 'question_survey')
->withPivot('id');
}
Now you can access the id from the pivot table:
$userSurvey->pivot->id;
Bonus, if you think that the pivot word just does not fit your wording style, just use the as method in your relationship to customize the variable name of the pivot attribute.
public function surveys()
{
return $this->belongsToMany('App\Question', 'question_survey')
->as('question_survey')
->withPivot('id');
}
Now you can access the id from the pivot table:
$userSurvey->question_survey->id;

Model doesn't show up on relationship right after saving?

For example
$user->transactions()->save($transaction);
dump($transaction->id); // id: 4
dd($user->transactions); // last id is 3
The $transaction that is saved does not show up in $user->transactions. This is a polymorphic relationship.
When you save a model through a relationship, all Laravel does is set the appropriate foreign keys. It doesn't set the newly saved model to the relation or add it to a collection.
If you want the model with updated relations use the fresh function.
$user->transactions()->save($transaction);
$user = $user->fresh('transactions');
Edit answer updated following #JCLee's correction to assign the result of $user->fresh().

Laravel how many relationship can be chained

I have a database composed by users, users_child, child.
I create a ONE to MANY relationship between Users and users_child, then i create a relationship between users_child and child. Now the below code work:
$test = users::find(1)->users_child
$test1= users_child::find(1)->child
Now i want to know if is possible to create a single row that link the three table like this:
$test = users::find(1)->users_child->child
I create the relationship in the model but in the db i don't create Foreign Key, it's a problem? on the model i specify the field for link table.
http://laravel.com/docs/5.1/eloquent-relationships#querying-relations
You can chain relationships like this:
$user = Users::with("users_child.child")->where("id",1)->first();
Each point will mean a relation stored in the first.
Out of users users_child will be taken and out of users_child child will be taken. (Relations)
foreach($user->users_child as $user_child) {
$user_child->child;
}
will get you the data you need.

Updating a pivot table in Eloquent

I've got a many to many relationship between a student and an institution_contact.
students should only ever have two institution_contacts and I have an attribute on the pivot table named type to be set as 1 or 2.
So, my pivot table looks like this:
institution_contact_student: id, institution_contact_id, student_id, type
I've run into difficulty in deciding how to approach the issue of adding/updating the pivot table. Let's say I have 100 students and I want to assign them a contact with the type of 1.
My current solution is to delete the contact then add it:
$students = Student::all(); // the 100 students
$contactId = InstitutionContact::first()->id; // the contact
foreach ($students as $student) {
// remove existing contact
$student
->institutionContacts()
->newPivotStatement()
->where('type', 1)
->delete();
// add new contact
$student
->institutionContacts()
->attach([$contactId => ['type' => 1]]);
}
However, I'm thinking that this is going to hit the database twice for each student, right? So would I be better off creating a model for the pivot table and removing all entries that matched the student id and the type then simply adding the new ones? Or would creating a model for the pivot table be considered bad practice and is there a better way of accomplishing this that I've missed?
Please note the reason I'm not using sync is because I'm relying on the type attribute to maintain only two contacts per student. I'm not aware of a way to modify an existing pivot without causing issues to my two contacts per student requirement.
Edit:
Instead of creating a model I could run the following code to perform the delete using DB.
DB::table('institution_contact_student') // the pivot table
->whereIn('student_id', $studentIds)
->where('type', 1)
->delete();
If I have understood your question correctly then you can use the updateExistingPivot method for updating your pivot table.But first of course you have to define the pivot in your relationship. For instance,
public function institutionContacts(){
return $this->belongsToMany('institutionContact')->withPivot('type');
}
after this, all you have to do is use the following code:
$student
->institutionContacts()
->updateExistingPivot($contactId, ["type" => 1]);
Hope this helps.

Resources