groupBy method can't insert or save a multiple values - php

I'm thinking why I can't insert or save the tables that I groupBy in the statement that I did. I group them properly but when I tried to insert this into my database it just get the first value in the column not all the values. I have a one to many relationship between departments and users
Die and Dump
As you can see here in "Department of Engineering" I have a users id which is 3 and 4. When I tried to insert this into database the first value is only that inserted.
Database Values
Controller
public function getDocuments()
{
$departmentRecipient = DB::table('users')->select('departments.department_name', 'users.id', DB::raw('group_concat(users.id)'))
->join('departments', 'departments.id', '=', 'users.department_id')
->groupBy('departments.department_name')
->get();
}
public function postDocuments(Request $request)
{
$document = new Document();
//Request in the form
$document->title = $request->title;
$document->content = $request->content;
$document->category_id = $request->category;
$document->save();
$user = Auth::user();
foreach($request->recipient as $recipientId)
{
$document->sentToUsers()->sync([ $recipientId => ['sender_id' => $user->id]],false );
}
}
View
<div class = "form-group">
<label for = "recipient" class = "control-label">Recipient:</label>
<select name = "recipient[]" multiple class = "form-control select2-multi" id = "myUserList">
#foreach ($departmentRecipient as $list)
<option value = "{{ $list->id }}">{{ $list->department_name }}</option>
#endforeach
</select>
</div>

Related

Method Illuminate\Support\Collection::save does not exist in Laravel

I have a dropdown list in a data capture view where a join is used in the Controller, but when I am trying to save the record, I am getting a below error.
Method Illuminate\Support\Collection::save does not exist.
I have tried to change the eloquent statement to
$energy = DB::table('vehicleslog')->join('vehicle', 'vehicleslog.vehicle_id', '=', 'vehicle.id')->first();
instead of
$energy = DB::table('vehicleslog')->join('vehicle', 'vehicleslog.vehicle_id', '=', 'vehicle.id')->first();
however that gives me a below error.
Call to undefined method stdClass::save()
Does anyone know what the correct one is?
Controller:
public function index()
{
// $energy = Maintenance::orderBy('id', 'desc')->paginate(5);
$energy = DB::table('vehicleslog')->join('vehicle', 'vehicleslog.vehicle_id', '=', 'vehicle.id')->get();
$cars = Vehicle::get();
$staff = Staff::all();
return view('admin.vmaintenance', compact('energy', 'cars', 'staff'));
}
public function store(Request $request)
{
// $energy = new Maintenance;
$energy = DB::table('vehicleslog')->join('vehicle', 'vehicleslog.vehicle_id', '=', 'vehicle.id')->first();
$cars = Vehicle::all();
$staff = Staff::get();
$energy->staff_key = $request->input('staff_key');
$energy->vehicle_id = $request->input('vehicle_id');
$energy->log_dt = $request->input('log_dt');
$energy->admin_time = $request->input('admin_time');
$energy->driving_time = $request->input('driving_time');
$energy->work_time = $request->input('work_time');
$energy->jobcard_count = $request->input('jobcard_count');
$energy->start_odo = $request->input('start_odo');
$energy->end_odo = $request->input('end_odo');
$energy->save();
return redirect('/vmaintenance')->with('success', 'data added');
}
View:
<label>Select Vehicle</label>
<select name="vehicle_id" >
#foreach($cars as $car)
<option value="{{ $car->id }}">{{ $car['reg_number'] }}</option>
#endforeach
</select>
Eager loading:
$energy = VehicleLog::with('vehicle')->first();
Also:
this variable never used in your store() action:
$cars = Vehicle::all();
$staff = Staff::get();
you can use fill() method:
$energy->fill($request->only([
'staff_key', 'vehicle_id', 'admin_time',
'driving_time', 'work_time', // ...
]));
Since you aren't using a model you'll need to just use an insert statement.
DB::table('vehicleslog')->insert([
'staff_key' => $request->input('staff_key'),
'vehicle_id' => $request->input('vehicle_id'),
'log_dt' => $request->input('log_dt'),
// etc........
)];

How to add records to a pivot table in Laravel

I have a user, student and subject model and I want to register a student into many subjects. So I created a StudentRegistration controller and in my create view I show all the subjects that belong to the course of the current logged in user.
StudentRegistration.php create function
public function create()
{
$user_id = Auth::user()->id;
$student_id = Student::where('user_id', $user_id)->first();
$course = $student_id->course->id;
$subjects = Subject::where('course_id', $course)->get();
return view('student.create', compact('subjects'));
}
In the create template I show all the subjects as checkbox because a user can register for multiple subjects.
{!! Form::open(['method' => 'POST', 'action'=>'StudentRegistration#store', 'files'=>true]) !!}
#foreach($subjects as $subject)
<div class="label-box">
{!! Form::label('name', $subject->name) !!}
{!! Form::checkbox('subject_id[]', $subject->id, null, ['class'=>'form-control']) !!}
</div>
#endforeach
<div class="form-group">
{!! Form::submit('Create User', ['class'=>'btn btn-primary']) !!}
</div>
{!! Form::close() !!}
I have this in my Student.php for the many to many relationship:
public function subjects()
{
return $this->belongsToMany('App\Subject');
}
I created a pivot table named Student_Subject. So, during the store, how can I save all the selected subjects into pivot table (student_subject).
I tried using this:
public function store(Request $request)
{
$data = $request->except('_token');
$subject_count = count($data['subject_id']);
for($i=0; $i < $subject_count; $i++){
$student = Student::where('user_id', Auth::user()->id);
$student->subjects()->attach($data['subject_id'][$i]);
}
}
But I get the following error:
"Method Illuminate\Database\Query\Builder::subjects does not exist."
And how can I view all the course subjects which the student is not registered at?
I have this:
Route::get('/studentsubjects', function(){
$student_id = Student::where('user_id', Auth::id())->first();
$course = $student_id->course->id;
$subjects = $student_id->subjects;
echo 'Registered at' .'<br>';
foreach ($subjects as $registered) {
echo $registered->name .'<br>';
}
$unregistered = Subject::where('course_id', $course)->except($subjects);
});
And see this error:
"Method Illuminate\Database\Query\Builder::except does not exist."
$student = Student::where('user_id', Auth::user()->id);
is not enough to get the Student model, you're only getting the query object here.
In order to actually get the student, use the following:
$student = Student::where('user_id', Auth::user()->id)->first();
Even better if user_id is the primary key for your model Student:
$student = Student::find(Auth::user()->id);
As a side note, you can access directly the user ID from the Auth interface using Auth::id() instead of Auth::user()->id, resulting in:
$student = Student::find(Auth::id());

Grammar::parameterize() must be of the type array

I got this error
Argument 1 passed to Illuminate\Database\Grammar::parameterize() must be of the type array, string given,
when I tried add array[] in my View using select form. But when I removed it I didn't get any error. I'm just trying to input a multiple value in my select list. Do I need to use foreach for this?
View
<div class = "form-group {{ $errors->has('approver') ? ' has-error' : '' }}">
<label for = "approver" class = "control-label">Approver:</label>
<select name = "approver[]" multiple class = "form-control select2-multi">
#foreach ($approver as $list)
<option value = "{{ $list->id }}">{{ $list->username }}</option>
#endforeach
</select>
#if ($errors->has('approver'))
<span class = "help-block">{{ $errors->first('approver') }}</span>
#endif
</div>
Controller
public function getDocuments()
{
$approver = DB::table('users')->where('id', '!=', Auth::id())->get();
return view ('document.create')->with('approver', $approver);
}
public function postDocuments(Request $request)
{
$this->validate($request,
[
'title' => 'required|regex:/(^[A-Za-z0-9 ]+$)+/|max:255',
'content' => 'required',
'category' => 'required',
'recipient' => 'required',
'approver' => 'required',
]);
$document = new Document();
$approve = new Approve();
$user = Auth::user();
//Request in the form
$document->title = $request->title;
$document->content = $request->content;
$document->category_id = $request->category;
$approve->approver_id = $request->approver;
$approve->save();
$document->save();
$document->sentToApprovers()->sync([$approve->id],false);
}
Update
I die and dump the $approver variable and gives a array of value.
Also die and dump the $request As you can see here I input the id of 4 and 5 in my select list.
Ok, your issue is that you're trying to save an array as a singular value where you need to iterate over the approvers instead.
Change your controller logic around to this:
foreach ($request->approver as $approver) {
$approve = new Approve();
$approve->approver_id = $approver;
$approve->save();
$document->sentToApprovers()->sync([$approve->id],false);
}
In my case i wanted to insert bulk data, therefore i got the error.
Then i used the
User::insert($arrayData)
and i'm done.
I got this error because I overwrote the constructor in a model. If you do so, make sure to pass the arguments array:
public function __construct(array $attributes = [], $something_else)
{
parent::__construct($attributes);
//...
$this->something_else = $something_else;
}
In my case i not mention the name in :-
$request->input();
so i just change with
$request->input("name");
then its works

groupBy only gets the first id

I have a many to many relationship between departments and users my pivot table is department_user. I wanted to select all the department_name depending of the user's department using groupBy method to merge all the department_name into one. See below my statement.
$departmentRecipient = DB::table('users')->select('departments.department_name', 'users.id')
->join('department_user', 'users.id', '=', 'department_user.user_id')
->join('departments', 'department_user.department_id', '=', 'departments.id')
->groupBy('departments.department_name')
->get();
Result using die and dump.
As you can see here I have an id of 4 under "Department of Engineering". My main problem is it doesn't fetch all the id under "Department of Engineering". But in my SQL I have id of 5 not only 4. How can I solve this problem? Any help would greatly appreciated. Please see result below.
Output:
This is the output of my list. I wanted to get all the users id belongs to the specific option for the user. But if I choose "Department of Engineering" it only gets the id of 4 not 5. I wanted to get 4 and 5 once.
Controlller:
public function getDocuments()
{
$departmentRecipient = DB::table('departments')->get();
return view ('document.create')->with('departmentRecipient', $departmentRecipient);
}
public function postDocuments(Request $request)
{
$this->validate($request,
[
'title' => 'required|regex:/(^[A-Za-z0-9 ]+$)+/|max:255',
'content' => 'required',
'category' => 'required',
'recipient' => 'required',
]);
$document = new Document();
//Request in the form
$document->title = $request->title;
$document->content = $request->content;
$document->category_id = $request->category;
$document->save();
$user = Auth::user();
foreach($request->recipient as $recipientId)
{
$document->sentToUsers()->sync([ $recipientId => ['sender_id' => $user->id]],false );
}
}
Model
User
public function departments()
{
return $this->belongsToMany('App\Models\Department', 'department_user');
}
Department
public function users()
{
return $this->belongsToMany('\App\Models\User', 'department_user');
}
View
<div class = "form-group">
<label for = "recipient" class = "control-label">Recipient:</label>
<select name = "recipient[]" multiple class = "form-control select2-multi" id = "myUserList">
#foreach ($departmentRecipient as $list)
<option value = "{{ $list->id }}">{{ $list->department_name }}</option>
#endforeach
</select>
</div>
From your given code it seems you are not using Eloquent ORM, you are doing it using Query Builder.
If you don't have a performance concern right now you can do it using separate queries. Like-
$departmentRecipient = DB::table('departments')->all();
foreach($departmentRecipient as $department){
$department->users = DB::table('department_user')->where('department_id',$department->id)->pluck('user_id');
}
But the better way is to use the eloquent with relationships. Define the many to many relationship in your eloquent model of Users and Departments (assuming you have eloquent model for them). You will find details about eloquent relationships at laravel documentation.
Update:
From the update of your post it is actually pretty easy to do what you want. If your Request contains the selected department id then you can do the following:
public function postDocuments(Request $request)
{
$document = new Document();
$document->title = $request->title;
$document->content = $request->content;
$document->category_id = $request->category;
$document->save();
//get the users list of the selected department id
$selected_department = $request->department_id; //this must be included in your POST data
$users = DB::table('department_user')->where('department_id',$selected_department)->pluck('user_id');
//now you have the list of the users id
foreach($users as $user){
// do what you need here
}
}
Update 2:
Following controller code might work for you.
Controller:
public function getDocuments()
{
// I am suggesting here to change the '$departmentRecipient' to '$departmentlist', as it is more meaningful. Also in your view
$departmentlist = DB::table('departments')->get();
return view ('document.create')->with('departmentlist', $departmentlist);
}
public function postDocuments(Request $request)
{
//same as you have till the $document->save()
....
....
//then do this
$recipients = array();
$departments = $request->recipient;
foreach($departments as $department){
$users = DB::table('department_user')->where('department_id',$department)->pluck('user_id');
$recipients = array_merge($recipients, $users);
}
//now you have a complete list of the users from selected departments
//Do as you intend to like this
$user = Auth::user();
foreach($recipients as $recipientId)
{
$document->sentToUsers()->sync([ $recipientId => ['sender_id' => $user->id]],false );
}
}

How to pass variable from foreach to view?

I'm trying to pass a variable from foreach to my view. So I can access this using in my select form. Because I have two tables M:M relationship between departments and user. I need to get all the department_name where the user_id belong. For me able to send a data via department_name Here what I did please take a look.
DB Diagram:
department_user
As you can see here user_id is the id of the user and document_id is where the users belong.
Model:
Department:
public function users()
{
return $this->belongsToMany('\App\Models\User', 'department_user');
}
User:
public function departments()
{
return $this->belongsToMany('App\Models\Department', 'department_user');
}
Controller:
public function getDocuments()
{
$departmentRecipient = DB::table('departments')->get();
foreach ($departmentRecipient as $department)
{
$department->users = DB::table('department_user')
->where('department_id', '=', $department->id)
->pluck('user_id');
}
return view('document.create')->with('department', $department);
}
I'm getting all the users_id when I die and dump my variable departmentRecipient.
View:
<div class = "form-group">
<label for = "recipient" class = "control-label">Recipient:</label>
<select name = "recipient[]" multiple class = "form-control select2-multi" id = "myUserList">
#foreach ($department as $list)
<option value = "{{ $list->user_id }}">{{ $list->department_name }}</option>
#endforeach
</select>
</div>
I wanted to foreach the $department in my Controller to my select form. But it always says.
Trying to get property of non-object (View: C:\Users\JohnFrancis\LaravelFrancis\resources\views\document\create.blade.php)
Goal:
Use the following loop to iterate through the department users and add them to pivot table.
foreach($request->department as $departmentId)
{
foreach(Department::find($departmentId->id)->users()->get() as $user1) //find the users belonging to the current department
{
$document->sentToUsers()->sync([ $user1->id => ['sender_id' => $user->id]],false );
}
}
Also remove the following code form your getDocuments() as it is redundant:
foreach ($departmentRecipient as $department)
{
$department->users = DB::table('department_user')
->where('department_id', '=', $department->id)
->pluck('user_id');
}
I don't see user_id property in your dumped value of $departmentRecipient object, that is why you are getting the error you mentioned. However, there is a users array inside of $departmentRecipient object, which you made inside your foreach loop. You are plucking every user_id which are in individual department and setting in a property named users of $departmentRecipient object, and so you are getting an array inside users property. Here I have a solution for you,
public function getDocuments()
{
$departmentRecipient = DB::table('departments')->get();
$departmentUsers = array();
foreach ($departmentRecipient as $department)
{
$users = DB::table('department_user')
->where('department_id', '=', $department->id)
->pluck('user_id');
foreach ($users as $userId) {
$departmentUsers[$userId] = $department->department_name;
}
}
return view('document.create')->with('department', $department)->with('departmentUsers', $departmentUsers);
}
and inside of your view loop through the variable $departmentUsers, like this,
#foreach ($departmentUsers as $userId => $departmentName)
<option value = "{{ $userId }}">{{ $departmentName }}</option>
#endforeach
This will work but as your department contains multiple users so you will get individual department name multiple time in your select2 dropdown. If you share more of what is your goal by select2 then may be I can help you to solve your problem in other way.
Moreover if you are interested to use of Eloquent then you can get rid of lots of foreach looping.
In your case you can have multiple users against each department. So to make it work correctly with your forearch code. You need to make sure you are getting one user record against each depart. So modify following line of code in controller.
$department->users = DB::table('department_user')->where('department_id', '=', $department->id)->pluck('user_id');
But you want to display all users of department then you have to change foreach loop code into view.
Try This Code
App/Department
public function users()
{
return $this->belongsToMany('App\Entities\User', 'department_user', 'user_id', 'department_id');
}
App/User
public function departments()
{
return $this->belongsToMany('App\Models\Department', 'department_user');
}
Controller
use App/User;
public function getDocuments($userId,User $User)
{
$getSpecificUser = $User->with('departments')->find($userid);
return view('document.create')->compact('getSpecificUser');
}
View
#foreach ($getSpecificUser as $getUser)
#if(empty($getUser->departments) === false)
#foreach ($getUser->departments as $departments)
<option value = "{{ $getUser->id }}">{{ $departments->department_name }}</option>
#endforeach
#endif
#endforeach

Categories