How to save record in database using belongs to many relation in laravel - laravel

I have three tables: restaurant_location, cuisine_restaurant_location and cuisines.
There is a list of all cuisines in my cuisines table. I have all the details of the restaurant in my restaurant_location table. A restaurant can have many cuisines so I made a table cuisine_restaurant_location in which there are two columns cuisine_id and restaurant_id. I have created a belongs to many relation in my restaurant_location model.
restaurant_location model
public function cuisines()
{
return $this->belongsToMany(Cuisine::class, 'cuisine_restaurant_location', 'restaurant_id', 'cuisine_id');
}
I have a form in which all the details of the restaurant along with cuisines is supposed to be added. Right now I am adding all the details of the restaurant. Now the question is how can I insert the cuisines in "cuisine_restaurant_location".
Controller
$rest = new restaurant_location;
$rest->name = $request->input('name');
$rest->description = $request->input('desc');
$rest->save();
$cuisine = new cuisine_restaurant_location
$cuisine_lists = $request->input('cuisines');
foreach ($cuisine_lists as $cuisine_list) {
$cuisine->name = $cuisine_list;
}

You can use the sync and attach methods, described in the Many to many section of the eloquent documentation, for that:
$rest->cuisines()->attach([$cuisineIds])
Where cuisineIds is the list of ids of the cuisines you want to relate.
The difference between sync and attach is that sync will remove all id's not present on the array of ids you are passing.

Try sync() method:
$h = [];
if (isset($input["cuisine_id"])) {
$h = $input["cuisine_id"];
}
$restaurant_location->cuisines()->sync($h);

Related

Laravel isDirty() & getOriginal() not working with pivot relationship in observer

In my project, I want to keep track of updated comments. So if a comment is updated, the old comment is saved in a comment_history table. I am using observer for this. But user can tag other users in a comment. So, I have a many-to-many pivot table comment_user.
I have defined a belongsToMany relationship in my comment model with the user model. So far I can insert it into comment_history when the comment field changes. But I also want to insert into comment_history when the tagged users are changed in a comment. I want the tagged user ids in comma-separated to be inserted in the old_tagged_users fields in comment_history. But isDirty() & getOriginal() doesn't work with pivot relationship.
class CommentObserver
{
public function updated(Comment $comment)
{
if($comment->isDirty('comment') || $comment->taggedUsers()->isDirty() ){
$history = new CommentHistory();
$history->old_comment = $comment->getOriginal('comment');
$history->old_tagged_users = //old tagged user_ids in comma separeted
$comment->history()->save($history);
}
return;
}
}

laravel Many Records to One single record....but how?

I have two tables, one is Users and the other is Loans. These have one to many relationship between them. One user can have many loans and one loan belongs to one User.
Now I want to get the user from the list of loans.
Loan::where('user_id', $user)->get()
This give me repeated array of sample user associated to the multiple loans. But I want to get only a single record, like many loans associate to one user.
I assume you already set up relationships between User & Loan Models
// App\User
public function loans() {
return $this->hasMany('App\Loan');
}
// App\Loan
public function user() {
return $this->belongsTo('App\User');
}
Get user from the list of loans
$user = Loan::where('user_id', $id)->first()->user;
// eager loading version
$loansWithUsers = Loan::with('user')->where('user_id', $id)->get();
Loans associate to one user
$loans = User::findOrFail($id)->loans;
// eager loading version
$userWithLoans = User::with('loans')->findOrFail($id);
For what I understand in your question, you want to get the user together with it's loan right ? Your query should like this.
$user_loans = User::with('loans')->where('id', $user_id)->get();
Get the user informations from loan table
Loan::where('user_id', $user_id)->with('user')->get()
Ge the users from loans table depends on brach id
Loan::where('branch_id', $branch_id)->with('user')->get();

Getting sum of field through polymorphic relationship in Laravel

I have two models, Payments_Distribution and Donation.
In my Donation model:
public function payments() {
return $this->morphToMany(Payments_Distribution::class, 'payable');
}
And I can save a payment distribution to the donation model using the following:
$distribution = new Payments_Distribution;
$distribution->payment_id = $payment->id;
$amount = $request->payment_details['amount'][$i];
$donation->payments()->save($distribution);
But I'm stuck on how to retrieve the sum of all the associated records' amount fields in the Payment_Distribution model table.
Would it be something like:
$donation->payments()->______ ->sum('amount');
Or something else? I'm still a bit new to polymorphic relationships.
In your code, you are not saving amount to the Payments_Distribution instance before using the ->save() method. Replace:
$amount = $request->payment_details['amount'][$i];
With:
$donation->amount = $request->payment_details['amount'][$i];

Laravel save / update many to many relationship

Can anyone help me on how to save many to many relationship? I have tasks, user can have many tasks and task can have many users (many to many), What I want to achieve is that in update form admin can assign multiple users to specific task. This is done through html multiple select input
name="taskParticipants[]"
The catch here is that through the same form (input) you can add/remove users, that's why I have to use sync().
Maybe I should start from the beginning but don't know where to start...
This is my User model:
public function tasks()
{
return $this->belongsToMany('Task','user_tasks');
}
Task model
public function taskParticipants()
{
return $this->belongsToMany('User','user_tasks');
}
TaskController
public function update($task_id)
{
if (Input::has('taskParticipants'))
{
foreach(Input::get('taskParticipants') as $worker)
{
$task2 = $task->taskParticipants->toArray();
$task2 = array_add($task2,$task_id,$worker);
$task->taskParticipants()->sync(array($task2));
}
}
}
This is structure of tables
tasks
id|title|deadline
user_tasks
id|task_id|user_id
tldr; Use sync with 2nd param false
Many-to-many relationship is belongsToMany on both models:
// Task model
public function users()
{
return $this->belongsToMany('User', 'user_tasks'); // assuming user_id and task_id as fk
}
// User model
public function tasks()
{
return $this->belongsToMany('Task', 'user_tasks');
}
In order to add new relation use attach or sync.
Difference between the two is:
1 attach will add new row on the pivot table without checking if it's already there. It's good when you have additional data linked to that relation, for example:
User and Exam linked with pivot table attempts: id, user_id, exam_id, score
I suppose this is not what you need in your situation:
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
$user->tasks()->attach([5,6,7]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,5,6,7]
2 sync on the other hand, will either remove all relations and set them up anew:
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
$user->tasks()->sync([1,2,3]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3]
or it will setup new relations without detaching previous AND without adding duplicates:
$user->tasks()->sync([5,6,7,8], false); // 2nd param = detach
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,7,8]
Here's my notes on how to save and update on all the Eloquent relationships.
in One to One:
You have to use HasOne on the first model and BelongsTo on the second model
to add record on the first model (HasOne) use the save function
example:    $post->comments()->save($comment);
to add record on the second model (BelongsTo) use the associate function
example:    $user->account()->associate($account);    $user->save();
in One to Many:
You have to use HasMany on the first model and BelongsTo on the second model
to add record on the first table (HasMany) use the save or saveMany functions
example:    $post->comments()->saveMany($comments);
to add record on the second model (BelongsTo) use the associate function
example:    $user->account()->associate($account);    $user->save();
in Many to Many:
You have to use BelongsToMany on the first model and BelongsToMany on the second model
to add records on the pivot table use attach or sync functions
both functions accepts single ID or array of ID’s 
the difference is attach checks if the record already exist on the pivot table while sync don’t
example: $user->roles()->attach($roleId);
in Polymorphic One to Many:
You have to use MorphMany on the main model and MorphTo on all the (***able) models
to add records on all the other models use the save
example:    $course->tags()->save($tag);
the pivot table should have the following columns:
. main model ID
. (***able) ID
. (***able) Type
in Polymorphic Many to Many:
You have to use MorphByMany on the main model and MorphToMany on all the (***able) models
to add records on all the other models use the save or saveMany
example:    $course->tags()->save($tag);
example:    $course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);
the pivot table should have the following columns:
. main model ID
. (***able) ID
. (***able) Type
in Has Many Through (shortcut):
You have to use HasManyThrough on the first table and have the normal relations on the other 2 tables
this doesn’t work for ManyToMany relationships (where there’s a pivot table)
however there’s a nice and easy solution just for that.
Here's an article I wrote, inspired by this answer. Important to check it: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
syncWithoutDetaching([$id_one, $id_two, $id_three]); is what you are looking for. Actually it does the exact thing [sync with 2nd param false] does!
Solved: Use the updateOrInsert(array $attributes, array $values = [])
DB::table('your_pivot_table')->updateOrInsert([
'col' => $someValue
],[
'otherColumn' => $otherVlaue,
]);
}
The sync function obliterates the exiting relationships and makes your array the entire list of relations. You want attach instead to add relations without removing others.
for those who are searching for adding pivot attributes (the middle table attributes), you can use syncWithPivotValues and it also has the second parameter like this
$user->tasks()->syncWithPivotValues($tasksIDs,['day_number' => $day],false);

delete multiple relationships in codeigniter datamapper orm

I have two models:
users and groups
user has many groups
and group has many users
I try to delete all groups of a user like this, which is not working
$user = new User(1);
$user->groups->delete_all();
Is there a solution to delete all multiple relationships for a model ?
if you want to delete data from multiple table and you have a relation like foreign key you can use this following function by just passing table names (array) and your field name..
function deleteMultiple($tables = array(),$condition = array())
{
if($condition)
$this->db->where($condition);
$this->db->delete($tables);
return;
}

Resources