Laravel 5.5 Can't remove category after editing - php

When I edited post I want to remove cancelled categories. I use sync method but its not working..
Edit Blade
<select class="form-control m-select2" id="m_select2_3" name="categories[]" multiple="multiple">
<optgroup label="Kategoriler">
#foreach($categories as $category)
<option value="{{$category->id}}" {{ in_array($category->id,$categoriesPost) ? 'selected' : '' }}>{{$category->category_name}}
</option>
#endforeach
</optgroup>
</select>
And Controller
public function update(StoreBlogPost $request, $id){
$post = Post::find($id);
$post->title = $request->title;
$post->caption = $request->caption;
$post->content = $request->input('content');
$post->save();
$post->categories()->sync($request->categories, false);
return redirect()->route('posts.index');
}
Any advice ?

You should set the second parameter of sync to true.
From the code,
/**
* Sync the intermediate tables with a list of IDs or collection of models.
*
* #param \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|array $ids
* #param bool $detaching
* #return array
*/
public function sync($ids, $detaching = true)
{
....
}
It means, the ids that didn't present in the $ids will be detached.

Related

How may I put a $_POST data into a database table?

It's been 3 weeks since I've started to learn symfony 4. I am trying to put the chosen data from the dropdown list into a database but I am not using a Form builder - the data is entered in html/twig and then stored into a variable $value.
I am wondering, though, how can I put this data from the variable $value into a database of choice (table User)? I mean, (if understood it right) when I use the form builder I am supposed to use ObjectManager $manager as following:
$manager->persist($value);
$manager->flush();
In this case I, honestly, have no idea of how I can put my data into a database.
Can anyone give me a clue?
twig
<select name="user">
{% for user in users %}
<option value="{{ user.idUser }},{{ user.name }}" label="{{ user.name }} {{ user.surname }}">{{ user.name }} {{ user.surname }}</option>
{% endfor %}
</select>
<button type="submit" id="article_form_save" name="article_form[save]">ADD</button>
controller
/**
* #Route("/attribution", name="attribution")
*/
public function create (Request $request) {
$users = $this
->getDoctrine()
->getRepository(User::class)
->findAll();
$value = $_POST;
dump($value);
return $this->render('database/Roles/attrib.html.twig', [
'users' => $users
]);
You can access your dropdown data from $_POST['user'] or you can use $request->request->get('user')
In order to save data into the database, you can create an object (Post for example) where you set the values you are retrieving from the request and then saving them.
You can do something like this:
<?php
/**
* #Route("/attribution", name="attribution")
*/
public function create (Request $request) {
$users = $this
->getDoctrine()
->getRepository(User::class)
->findAll();
$user = $request->request->get('user');
$manager = $this->getDoctrine()->getManager();
$post = new Post();
$post->setUser($user); // I suppose the user property in your post is just an integer not an object
$manager->persist($post);
$manager->flush();
dump($user);
return $this->render('database/Roles/attrib.html.twig', [
'users' => $users
]);
?>
This is just an example, which you can adapt it to your needs.
Your value should have only the user id. Change
<option value="{{ user.idUser }},{{ user.name }}"
to
<option value="{{ user.idUser }}"
Then, you can get the user like this:
$userId = $request->request->get('user'); //this will not be a user entity, but only an id
Which will return the user id.
Then you need to retrieve the user via your repository and save it.
Inject your user repository and entity manager by type-hinting them in your function arguments:
public function create (Request $request, UserRepository $repository, EntityManagerInterface $entityManager) {
do a findOneBy:
$user = $repository->findOneBy(['id' => $userId]);
Set the user to the article and save it
$article.setUser($user);
$entityManager->persist($article);
$entityManager->flush();
PS: using Symfony forms would make it waaay simpler.

Laravel eloquent arrays to remove matching

I have to two eloquent returned arrays :
$services = \App\Service::all();
$userService = \App\UserService::where('user_id', Auth::user()->id)->get();
What i tried is that :
#foreach($services as $service){
#foreach($userServices as $userService){
#if($userService->service_id != $service->id)
<option value="{{ $service->id }}">{{ $service->name }}</option>
#endif
#endforeach
#endforeach
But its repeating the options, And creating mess.
What will be a good approach ?
You can try this out:
$userServices = \App\UserService::where('user_id', Auth::user()->id)
->pluck('service_id')->toArray();
$services = \App\Service::whereNotIn('id',$userServices)->get();
//Now you can loop through services
#foreach($services as $service){
<option value="{{ $service->id }}">{{ $service->name }}</option>
#endforeach
Hope it helps...
You need to use nested relations in your model. Like this;
class Service extends Model
{
public function user_service()
{
return $this->hasMany(UserService::class, 'user_id');
}
}
And Controller
$user_id = Auth::user()->id;
$services = Service::with(['user_service' => function ($query) use ($user_id) {
$query->where('user_id', $user_id);
}])->get();
return view('page', compact('services'));
i have read the code
$services = \App\Service::all();
$userService = \App\UserService::where('user_id', Auth::user()->id)->get();
and
#foreach($services as $service){
#foreach($userServices as $userService){
#if($userService->service_id != $service->id)
<option value="{{ $service->id }}">{{ $service->name }}</option>
#endif
#endforeach
#endforeach
Userservice is sufficient to what you want to do, no need to retrieve data twice. you can simply find all service for the logged user in you query
$user_id = Auth::user()->id;
return Service::with(['user_service' => function ($query) use ($user_id) {
$query->where('user_id', $user_id);
}])->get();
or try to make a inner joins with raw query.
If you don't want to change your approach just change != to ==
#if($userService->service_id == $service->id)
Or if you want a good approach try eloquent.
Your models seems to be many to many relationship
Visit this link https://laravel.com/docs/5.4/eloquent-relationships#many-to-many

Laravel Form Building Not Passing Array Of Items

I passed my tags and on my form I have a multi-select. Although when I do tags[] nothing gets passed in. If I do just tag then only one of them submits.
public function create()
{
$categories = Category::pluck('name', 'id');
$tags = Tag::pluck('name', 'id');
return view('posts.create')->withCategories($categories)->withTags($tags);
}
{{ Form::label('tags', "Select Tag")}}
{{ Form::select('tags[]', $tags, null, ['class' => 'selectpicker', 'multiple', 'data-live-search="true"', 'data-actions-box="true"', 'data-width="100%', 'show-menu-arrow']) }}
It could be a glitch in the current version Laravel / Form Builder. If you do the old fashion select way it works as it should.
public function create()
{
$categories = Category::pluck('name', 'id');
$tags = Tag::all();
return view('posts.create')->withCategories($categories)->withTags($tags);
}
<select name="tags[]" class="selectpicker show-tick" multiple data-live-search="true" data-actions-box="true" show-menu-arrow>
#foreach ($tags as $tag)
<option value="{{$tag->id}}">{{$tag->name}}</option>
#endforeach
</select>

laravel call to a member function categories() on integer

I am trying to update and existing record in pivot table for many to many relationsip with laravel.
I have store function that work :
public function store(Request $request)
{
$produk = new product($request->input()) ;
$feat = (boolean)$request->input('featured');
$input = $request->all();
$input['featured'] = $feat;
$inputproduk = product::create($input);
$inputproduk->categories()->attach($request->input('kat_id'));
return redirect()->back()->with('message', 'Memasukkan Data Produk Berhasil');
}
But why my update function didn't work???
public function update(Request $request, $id)
{
$produk = Product::FindorFail($id);
$produk = new product($request->input()) ;
$input = $request->except('_method', '_token', 'picture', 'kat_id');
$inputproduk = product::whereId($id)->update($input);
$inputproduk->categories()->sync($request->input('kat_id'));
return redirect()->back()->with('message', 'Mengedit Data Produk Berhasil');
}
The error is :
Call to a member function categories() on integer
What is that mean? Please help me.
View :
<div class="form-group">
<label for="KategoriProduk">Kategori Produk</label>
<select class="form-control" name="kat_id[]" multiple>
#foreach($kategoris as $value)
<option value="{{$value->id}}">{{$value->namekat}}</option>
#endforeach
</select>
</div>
I only post partially because if I post it all then the question is just full of code. Tell me if you need more.
It's because of the following line.
$inputproduk = product::whereId($id)->update($input);
When you call update it will return an integer not a product object.
What you can do is first get the product and then update.
$inputproduk = product::whereId($id)->first();
$inputproduk->update($input);
$inputproduk->categories()->sync($request->input('kat_id'));

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