groupBy only gets the first id - php

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 );
}
}

Related

How can I save a new column data into laravel pivot table?

I have this 3 table:
stations (id,station_name)
products (id,product_name)
pivot table
product_station (station_id,product_id, tank_volum)
Station Model
public function products(){
return $this->belongsToMany(Product::class)
->withTimestamps()
->withPivot('tank_volume');
}
Product Model
public function stations(){
return $this->belongsToMany(Station::class);
}
I'm trying to create a station with many products and every product
have it's tank volume but i can't save the tank volume value to
database:
product_station table
this is my controller:
public function store(StationsRequest $request)
{
// dd($request);
$input = $request->all();
if($file = $request->file('photo_id')) {
$name = time() . $file->getClientOriginalName();
$file->move('images', $name);
$photo = Photo::create(['file'=>$name]);
$input['photo_id'] = $photo->id;
}
$station = Station::create($input);
$station->products()->sync($request->products , false);
return redirect('/admin/stations');
}
Q: How can i Save Tank volume inside product_station table "pivot table" ?
if you want to sync() related extra fields :
$product_ids = [];
foreach ($station->products as $product) {
//collect all inserted record IDs
$product_ids[$product->id] = ['tank_volume' => 'tank_volume_value'];
}
//if you want to pass new id from new query
//$product_ids['new_created_product->id'] = ['tank_volume' => 'tank_volume_value'];
then
$station->products()->sync($product_ids);
in this case, better use attach() :
$station = Station::create(['fields']);
$station->products()->attach([$product->id => ['tank_volume'=>'value']]);

How to query two tables in Laravel

I am trying to query two tables in Laravel when the user submits a form. The data is stored in the transaction table and I can also update the Account table by adding the $transactions->amt with $account->total.
I tried doing this;
public function store(Request $request)
{
$account = DB::table('users')
->join('accounts', "users.id", '=', 'accounts.user_id')
->select('users.*', 'accounts.*')
->first();
$transaction = new Transaction();
$data = $this->validate($request, [
'baddress'=>'required',
'package'=>'required',
'amt'=>'required',
]);
$transaction->username = $account->username;
$transaction->baddress = $request->input('baddress');
$transaction->package = $request->input('package');
$transaction->amt = $request->input('amt');
$transaction->fund_option = "Fund";
$transaction->save();
$bal= $transaction->amt + $account->total;
$account->amt_paid = $bal;
$account->total = $bal;
$account->save();
return redirect('/transfer')->with('success', 'Transaction has been made');
}
but I got this error:
Call to undefined method stdClass::save()
How can I find the best method to do this?
That error occur because $account is not collection. method save() is method from model collection.
if you want update you can use this code like.
$accountUpdate = DB::table('accounts')
->where('id', $account->id)
->update(['amt_paid' => $bal, 'total' => $bal]);
but if you want to use method save() then you have to call $account from model.
$account is a row made by your join (users.* and accounts.*) so it's a stdClass, not an Eloquent model. You don't have a save() method
in order to do this you should have a relationship between User model and Account model:
//Account.php
public function user(){
return $this->belongsTo("App\User");
}
........
//User.php
public function account(){
return $this->hasOne("App\Account");
}
then you can retrieve Account from your User:
$user = User::first();
$account = $user->account;
[....]
$account->amt_paid = $bal;
$account->total = $bal;
$account->save();
You have to use like this. This is simple as like as much
$accountModelUpdate = DB::table('accounts')
->where('user_id', $account->id)
->update(['amt_paid' => $bal, 'total' => $bal]);

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 method can't insert or save a multiple values

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>

Laravel 4 Creating Form for adding record with relationship

I have created very basic Model. I have persons table and emails table.
Also I have create a link in the persons/show.blade.php ("Add mail").
My models are
class Person extends Eloquent {
protected $table = 'persons';
public function email()
{
return $this->HasMany('Email');
}
}
and
class Email extends Eloquent {
protected $table = 'emails';
public static $rules = array(
'email'=>'required|unique:emails'
);
public function person()
{
return $this->belongsTo('Person');
}
}
How can I pass the $person->id to the new Controller?
In my show.blade.php for Person I added
{{ HTML::linkRoute('email.adduseremail','Προσθήκη Email',array($person->id))}}
and I added to my EmailController
public function adduseremail($id)
{
return View::make('email.createforuser',['id'=>$id]);
}
public function storeforuser($pid)
{
$validator = Validator::make(Input::all(),Email::$rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all('<li>:message</li>') as $message)
return Redirect::back()->withInput()->WithErrors($messages);
}
$person = Person::FindorFail($pid);
$email = new Email;
$email->email = Input::get('email');
$email->person()->associate($person);
$email->save();
return Redirect::route('person.index');
}
and my createforuser view is
<p>
{{Form::open(['route'=>'email.storeforuser'])}}
<div>
{{Form::label('email', 'Email:')}}
{{Form::input('text', 'email')}}
{{$errors->first('email')}}
</div>
</br>
<div>
{{Form::submit('Submit')}}
</div>
{{Form::close()}}
<p>
I keep getting Trying to get property of non-object (View: /var/www/laravel/app/views/email/show.blade.php)
Is there any example using Form and Models for inserting new objects to the database for 'belongsTo' Relationship? I couldn't find anything complete , just partial examples.
I generally use laravel sessions or laravel cache to tempererally save an id that i need to use later like:
Session::set('personId',$person->id);
Session::get('personId');
The same is for cache except cache will only last for the current request session is persistent for the session
Hope that helps
I am no sure if I 'm supposed to answer my own question but finally I found a solution.
I set two new routes
Route::post('email/adduseremail/{pid}', array('uses'=>'EmailController#adduseremail','as' => 'email.adduseremail'));
Route::post('email/storeforuser/{pid}', array('uses' =>'EmailController#storeforuser','as' => 'email.storeforuser'));
and created the corresponding methods in my Controller
public function adduseremail($id)
{
$pname = Person::Find($id)->name;
$psurname = Person::Find($id)->surname;
return View::make('email.createforuser',array('id'=>$id,'name'=>$pname, 'surname'=>$psurname));
}
and
public function storeforuser($pid)
{
$validator = Validator::make(Input::all(),Email::$rules);
if ($validator->fails())
{
$messages = $validator->messages();
foreach ($messages->all('<li>:message</li>') as $message)
return Redirect::back()->withInput()->WithErrors($messages);
}
$person = Person::FindorFail($pid);
$email = new Email;
$email->email = Input::get('email');
$email->person()->associate($person);
$email->save();
return Redirect::route('person.show',array($person->id));
}
then on my view blade pages I can pass the parameters from View to Form and so on
person.show.blade.php
{{Form::Open(array('route' => array('email.adduseremail', $person->id),'method' => 'POST','style'=>'display:inline;'))}}
{{Form::submit('Add Email')}}
{{Form::close()}}
and
email.createforuser.blade.php
{{Form::open(array('route'=>array('email.storeforuser',$id),'method' => 'POST','style'=>'display:inline;'))}}
{{Form::label('email', 'Email:')}}
{{Form::input('text', 'email')}}
{{Form::submit('Submit')}}
Hope it helps others also

Categories