updating related tables from a controller laravel - php

Hi I’ve a users and education table. A user can have multiple school or college. So its one to many relationship. education table has school, from_year, to_year and user_id (fk) I want to update the user table as well as education table from a PUT request to users/{id} with email,school, from_year, and to_year fields.
// UsersController.php
public function update(Request $request, $id)
{
$user = User::find($id);
if (!$user) {
return $this->respondNotFound('User not found');
}
$input = $request->all();
$input = array_filter($input, 'strlen');
//$user->update($input);
//Get array of school records
// $user->educatoion->push($records) // don't know what will come here to update the education table
// or may be $user->push(); // don't know
return $this->respond([
'data' => $user,
]);
}

Try to keep it as simple as possible.
If this is your first time updating multiple tables at once, draw up a diagram of the process. This way you can identify the correct order of updates.
Take care to note any formatting that has to done on each value.
Laravel has some great functionality in regards to binding input to a model using ->update($data)
However, when binding to multiple models, you might run into issues with duplicate field names.
Update:
To create a education row from the $user model:
$education = new Education(array('school' => 'Harward', 'from_year' => 1999, 'to_year' => 2016));
User::find($id)->education()->save($education);

Related

How to add pivot table when inserting data to database in Laravel 8

maybe someone know how to insert pivot table in Laravel 8 automatically every i insert counselings table?
I have Model Counseling n to n Problem,
Input form
counselings table
problems table
Counselings Model
Problem Model
Controller
public function create()
{
return view('admin.counseling.create', [
'title' => 'Tambah Bimbingan dan Konseling',
'students' => Student::all(),
'problems' => Problem::all()
]);
}
public function find_nis(Request $request)
{
$student = Student::with('student_class', 'counselings')->findOrFail($request->id);
return response()->json($student);
}
public function store(Request $request)
{ dd($request->all());
$counseling = new Counseling();
$counseling->student_id = $request->student_id;
$counseling->user_id = Auth::user()->id;
$counseling->save();
if ($counseling->save()) {
$problem = new Problem();
$problem->id = $request->has('problem_id');
$problem->save();
}
}
You can insert into a pivot table in a few different ways. I would refer you to the documentation here.
Attaching
You may use the attach method to attach a role to a user by inserting
a record in the relationship's intermediate table:
Example:
$problem->counselings()->attach($counseling->id);
Sync
You may also use the sync method to construct many-to-many
associations. The sync method accepts an array of IDs to place on the
intermediate table. Any IDs that are not in the given array will be
removed from the intermediate table.
Example:
$problem->counselings()->sync($counselingsToSync);
Toggle
The many-to-many relationship also provides a toggle method which
"toggles" the attachment status of the given related model IDs. If the
given ID is currently attached, it will be detached. Likewise, if it
is currently detached, it will be attached:
Example:
$problem->counselings()->toggle($counselingsToToggle);
I would change your store() method to something like this :
public function store(Request $request)
{
$counseling = Counseling::create([
'student_id' => $request->student_id,
'user_id' => Auth::user()->id
]);
if($request->has('problem_id'){
$counseling->problems()->attach($request->problem_id);
//return something if problem id is in request
}
//return something if problem id is not there
}

Updating DB tables based on relationships Laravel 5.8 and Eloquent

I have a problem with updating tables that belongTo another table.
I have a users table and a recipes table. The Recipe model belongsTo the User model and the User model hasMany Recipe.
Each recipe is shown in my index view as a small card and on that card, as well as on each individual show page, I am printing recipe->author. When a recipe is created, it takes the username attribute from the users table and sets this as the author attribute on the recipes table. However, when I update the username of a user, the author attribute in the recipes table does not update accordingly.
User Model
public function recipes(){
return $this->hasMany('App\Recipe');
}
Recipe Model
public function user(){
return $this->belongsTo('App\User');
}
Can I possible add some logic in my UserController to account for this when I update a user?
UserController#update
$user = Auth::user();
$this->validate(request(), [
'name' => 'required',
'username' => 'required',
]);
// Handle File Upload
if(request()->hasfile('profile_pic')){
// Get filename with extension
$fileameWithExt = request()->file('profile_pic')->getClientOriginalName();
// Get just filename
$filename = pathinfo($fileameWithExt, PATHINFO_FILENAME);
// Get just extension
$extension = request()->file('profile_pic')->getClientOriginalExtension();
// Filename to store
$fileNameToStore = $filename . '_' . time() . '.' . $extension;
// Upload Image
$path = request()->file('profile_pic')->storeAs('public/profile_pictures', $fileNameToStore);
} else {
$fileNameToStore = 'noimage.jpg';
}
$user->name = request('name');
$user->username = request('username');
$user->description = request('description');
$user->location = request('location');
if(request()->hasFile('profile_pic')){
$user->profile_pic = $fileNameToStore;
}
$user->push();
$user_id = Auth::user()->id;
return redirect()->route('user', ['id' => $user_id]);
}
I have read the Laravel docs and can't find anything that will quite do what I am looking for. Would appreciate any guidance!
You mean you store username in users, and you want to store the exact username in the author of recipes?
Why not you just reference the name using relationship $recipe->user->username. It would query your users table based on your user_id in your recipes and get that username for you.
So that you're not storing duplicating data in your database. There should be only one Single Source of Truth. You can get your user data based on your user_id, there's no point to store another set of data and keep updating it when the source is changed.
If you find querying whole User model a bit of heavy, then you can use Recipe::with('users:id,username')->get() to query only the username.
Or
If you want to maintain the current $recipe->author, you can:
// Recipe class
public function getAuthorAttribute() {
return $this->user->username;
}
If you set up the foreign keys on your migration files, you may add the ->onUpdate('CASCADE') clause to the username foreign on the recipes table migration.
Note: the onCascade foreign constraint would work outside of Laravel too, as it relies only on the database engine's support for foreign keys.
Anyways, be careful with your validation as you have to be sure the new chosen username isn't already used by someone else.
Assuming your User model is connected to the users table and has an id primary key, make sure that you set the username column as unique in the database, and **validate* user input accordingly.
The former is done by editing once again your migration.
The latter is solved by modifying your rules like these ones:
// Do not forget the Rule import at the top of your controller
use Illuminate\Validation\Rule;
// Then in your method
$this->validate(request(), [
'name' => 'required',
'username' => [
'required',
Rule::unique('users', 'username')->ignore($user)
]
]);
Note: if you modify migrations you have to rerun them in order to apply the modification.

Laravel Custom Relationship

Very silly situation, The point is I can not change the database architecture because its a running e-commerce business having more then 1m active users.
Here is my situation.
Table User:
Table Store:
Both have same primary key, mean we can call the one to one relation.
But now I have to create belongs to many relation form Store to User.
store table have two columns
slug
parentId
Now I need to get all users having slug of store
So my query is
select * from users where id IN (select id from store where slug = ?);
How can I create a relation in this situation.
Hey there i would try to answer in detail as much as possible.
Create the following relationships:
For store:
public function users(){
return $this->hasMany(User::class, 'id' ,'slug');
}
For user:
public function store(){
return $this->belongsTo(Store::class);
}
Create a new controller and write a new function as below:
public function getStoreUsers(){
$users = Store::where('slug','yourvalue')->firstOrFail()->users;
return response()->json($users);
}
The function above will return a collection of users which have theirs 'id' equals to store 'slug'
In case if you have many stores you can do the follwing:
public function getStoreUsers(){
$stores = Store::all();
$storeUsers;
foreach($stores as $store){
$users = $store->users;
$storeUsers[$store['id']] = array($users);
return response()->json($storeUsers);
}
}
This function will return an array of users of each store.
I have answered according to my understanding of your question if any erros occur please reply below so i can fix if possible. I Hope this is what you wanted if not let me know.
UPDATE:
This is what i could understand from your request.
Store a , store b , store c has slug = xyz.
you have 50,000 users. 10,000 of them has slug xyz. and you need the information of those 10,000 users. if thats the case then the code below will help you out.
public function getStoreUsers(){
$slugtomatch = 'xyz';
$result;
$stores = Store::where('slug',$slugtomatch)->get();
foreach($stores as $store){
$users = $store->users;
$result = array($users);
}
return response()->json($result);
}
This will return an array of users those have the $slugtomatch value in their slug fields.

collection to string in laravel 5.2 query builder

I want to make query in laravel 5.2 to fetch agencies table which has a foreign key with organizations table using agencies.organization_id=organizations.id. Now Users table has also foreign key with organizations table using users.organization_id=organizations.id. Now how to fetch agency table that which agencies are linked with users_id.
public function postagency(Request $request) {
$user_id = $request->user_id;
$org_id = User::where('id', $user_id)->pluck('organization_id')->first();
$postagencies = agency::where('organization_id', $org_id);
echo $postagencies;
}
For what I understand is that an user can only be under one organisation and an organisation has many agencies. If not please say so and I will alter my answer.
First of all set your relationships inside your models. An example would be:
// User.php
public function organization()
{
return $this->belongsTo('App\Organization'); // App\Organization can be changed depending on the used namespace
}
More info can be found here. If you need some more examples just ask.
After you have created these relationships you can retrieve your agency like this:
$user= User::find($request->user_id);
if (!$user) ... // Check if user exists
$agencies = $user->organisation->agencies;
If I need to explain things in more detail just ask. Hope this helps :)

GroceryCrud set a n-n relation with where clause

I have three tables (simplified) which are:
And I have to display all houses for each user.
In my controller I have a function like this:
public function create_houses_table($usr_id)
{
$crud = new grocery_CRUD();
$crud->set_language("italian");
$crud->set_theme('datatables');
$crud->set_subject('Casette');
$crud->set_table('tbl_houses');
$crud->set_relation_n_n('Casette',
'tbl_users_houses',
'tbl_users',
'house_id',
'user_id',
'usr_name',
NULL,
array('user_id' => $usr_id));
...
}
and what I get is this:
Every time I select a user from the combo I need to refresh my list filtering on usr_id...but I get always all the houses.
What I'm wrong?
This is not the intended usage for set_relation_n_n (it will show all the user houses in one field inside the user row).
What you want can be better done listing from tbl_users_houses, filtering by client with $crud->where() and linking with the other tables with two simple relations.
If I understand correctly you are trying to fetch only the records for the logged in User... and u have multiple users per house, hence the n-n relation.
I also faced this problem and here's what I did.
$myprojects = $this->admin_model->get_employee_projects($this->user_id);
$myprojectids = array_column($myprojects, 'id');
//get only one column from the multi-dimensional array
$crud->where("`projects`.id IN", "(" . implode(",", $myprojectids) . ")", false);
// the false disables escaping
$crud->set_relation_n_n('assigned_employees', 'project_employees', 'employees', 'project', 'employee', 'name');
//Only so it also still shows the name of Users assigned
So basically projects here is like houses, and I am using the WHERE IN clause to filter the records based on the projects I get from my model method...

Categories