We help IT Professionals succeed at work.

Could you point a way to enable/ disable an like icon depending on the user had clicked it before or not?

Eduardo Fuerte
Eduardo Fuerte asked
on
Hi Experts


Could you point a way to enable/ disable an like icon depending on the user had clicked the icon before or not?

Accordingly with:

img004
The user has the right of click the "Like" of  a photo once and after that he coudn't do nothing else, the like icon must to be disabled.
If the user reenter the page the like icon for the photo that had received a "like" must to stay disabled, also, by using the user's id.

The actual view:

@extends('layouts.appinterno')

@section('content')

	<div class='row'>

	{{ csrf_field() }}
    <input type="hidden" id="hdnCurtiu" value="{{ $curtiu }}">

        <div class="col-md-12 col-sm-12">
               
                <section class="row">
               
                        @foreach($vitrinesX->chunk(3) as $row)
                        
                            @foreach($row as $vitrine)
                          
                               <div class="col-sm-12 col-md-4">
                               
                                    <div class="box-noticias">
                                       	<a href="javascript:void(0);" onclick='xxx.vitrine.abrirVitrine({{$vitrine->id}});' >
                	    				{{$vitrine->titulo}}
                	    			    </a>                    
                                    </div> 
                                    
                                   	<p id="like" class="likes" onclick="xxx.vitrine.salvarEscolha({{ $vitrine->id }}, 1)">
    				                    <i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu_{{ $vitrine->id }}">{{ $vitrine->qtdeCurtiu }}</span>
    				               	</p> 
                     
                               </div>     
                              
                            @endforeach
                            
                        @endforeach
                          
                                                  
                </section>
			</div>

	</div>
@endsection


@section('scripts')

	<script src="{{ asset('js/xxx/xxx.Formatadores.js').'?v='xxx(uniqid()) }}" ></script>
	<script src="{{ asset('js/xxx/xxx.Vitrine.js').'?v='xxx(uniqid()) }}" ></script>

	<script>
		$(document).ready(function() {
			if($('#hdnCurtiu').val() == "1")
				$('#like').addClass('like');
			else if($('#hdnCurtiu').val() == "0")
				$('#dislike').addClass('like');
		})
	</script>

@endsection

Open in new window


I guess when the page starts it must to be checked on the existent jQuery code

JS code for the view (where I guess it must to be checked):

Vitrine.prototype.abrirVitrine = function(id) {
  $.ajax({
    url: "/vitrine/" + id + "/obter",
    method: "GET",
    error: function() {
      xxx.openModalCustom(
        "Erro",
        "Erro ao obter a notĂ­cia.",
        "Entendi",
        "error"
      );
    },
    success: function(data) {
      datacriacao = xxx.formatadores.DataBDParaDataBrasil(
        data.retorno.created_at
      );
      titulo = data.retorno.titulo;
      subtitulo = data.retorno.subtitulo;
      conteudo = data.retorno.conteudo;
      url = data.retorno.url;
      $("#datacriacao").html(datacriacao);
      $("#titulo").html(titulo);
      $("#subtitulo").html(subtitulo);
      $("#conteudo").html(conteudo);
      $("#image").attr("src", url);
      $("html, body").animate(
        { scrollTop: $("#datacriacao").offset().top },
        1000
      );
    }
  });
};

Open in new window



Controller code (where the above JS calls the obter method):
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

use Debugbar;
use DB;

class UserVitrine extends Model
{
    public function obter($user_id, $vitrine_id){
    
        return UserVitrine
            ::where('user_id', \DB::raw($user_id))
            ->where('vitrine_id', \DB::raw($vitrine_id))
            ->first();
    }
    
    public function obterCurtidasPorVitrine($vitrine_id, $curtiu){

        return UserVitrine
            ::where('vitrine_id', \DB::raw($vitrine_id))
            ->where('curtiu', \DB::raw($curtiu))
            ->count();
            
    }		
    
 		
}

Open in new window


Thanks in advance!
Comment
Watch Question

Hi,

I guess you want to disable the button not only the icon?

So you can add the disabled to the button
here is an example with the Bootstrap class
<button type="button" class="btn btn-lg btn-primary" disabled>Primary button</button>

Open in new window


You will need some server side to apply the class based on your requirements and a way to remember the state.
You can save the state to DB (this will kept the value for that user even if he clear the browser cache)

or you can use localstorage or sessionstorage but the user can clear the cache and the saved value will be lost.
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

**Remember that this can be easily edited from browser console so you may want to have server side validation to make sure.
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
Hey Eduardo,

Based on previous conversations we've had ... remember that your Vitrines has a many-to-many relationship with the Users where you record the Likes and Dislikes.

Using that, you should be able to attach a list of Users to each Vitrine. Then you can check that list against the current User and if they exist in the list, then you know they've Liked or Disliked the Vitrine before, so you can set the buttons to disabled.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi Chris

Hard to me how to implement that...

1. Something like that at VitrinesController
 
// Previous data (last question)
           $vitrinesX = Vitrine
                ::vigente()
                ->ativa()
                ->aprovada()
                ->global(Auth::user()->tipoparticipante_id)
                ->orderBy('id','desc')
                 ->withCount([
                        'user_vitrines as qtdeCurtiu' => function (Builder $query) { $query->where('curtiu', 1); },
                        //'user_vitrines as dislikes' => function (Builder $query) { $query->where('curtiu', 0); }
                    ])
                    ->get();

// The new Collection to be send to the view:  Needed columns vitrine_id and user_id 

$data = Vitrine::with('user_vitrines')->get();

dd($data);  // Difficult to obtain informations here
  

Open in new window



Could you check?
Most Valuable Expert 2018
Distinguished Expert 2018
Hey Eduardo,

There are a couple of ways you can do this. Probably the easiest way is to atatch a list of UserIds to each Image. To do this, I'll assume you have your many-to-many realtionshps set up correctly.

I'll give you a quick example, but I'll need to use English - hope you can follow that. Let's assume we have 2 models - User & Image. The 2 models will have a many-to-many realtionship (an image can be voted on by many users // a user can vote on many images), so we'll have a pivot table to link the 2. On that pivot table, we'll store the extra info a vote column (used to indicate a Like or Dislike). The basics of this means that we end up with 3 tables in the DB, for example:

users
    id
    name

images
    id
    title
    filename

image_user
    id
    user_id
    image_id
    vote

Open in new window

We set up the relationships at the Model level where we can tell Laravel to include the Vote data from the pivot table.

class User {
    public function images() {
        return $this->belongsToMany(Image::class)->withPivot('vote');
    }
}

class Image {
    public function users() {
        return $this->belongsToMany(User::class)->withPivot('vote');
    }
}

Open in new window

This now means that for each User we can access the Images they've voted on - $user->images(); and for each Image, we can access the Users who have voted on it - $image->users();

Now, in your controller, the trick is to retreive the list of IDs for the Users that have voted on an Image and attach that to each image. Take a look at this:

$images = Image::with('members')->get()
    ->each(function($image) {
        $image->votedBy = $image->members->pluck('id');
    });

Open in new window

What we're doing here is loading all images from the database, along with the related members. We're then looping over each image and setting a new property called votedBy. The value of this new property is a collection of Member IDs. Now for each image in our collection, we end up with something like this:

$image->title = "Image 1"
$image->filename = "image1.jpg"
$image->votedBy = [1, 5, 7, 10, 13] <-- This shows the IDs of Users who have voted on this image.

You then pass that data ($images) into your View:

return view('yourview', compact($images));

And then loop through your $images collection to output the info. During the loop, you check to see if a given user ID exists in the votedBy collection and act accordingly:

@foreach ($images as $image)
    @php $hasUserVoted = $image->votedBy->contains($userId); @endphp
    <div>
        <h2>{{ $image->title }}</h2>
        <button {{ $hasUserVoted ? 'disabled' : '' }}>Like</button> <button {{ $hasUserVoted ? 'disabled' : '' }}>Dislike</button>
    </div>
@endforeach

Open in new window

All we're doing here is checking whether the votedBy collection contains a given userId, and setting a variable to either true or false. We then use that variable to decide whether to echo 'disabled' into the button or not.

Hope that all makes sense :)
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi Chris

Thank you for so elaborated reply.

Trying to correct correlate your code to what I have here (equivalent to the last question)


img001

On the User Model I coded:

public function vitrines() {
	return $this->belongsToMany(Vitrines::class)->withPivot('user_vitrines');
} 
//------------------------------
//Correspondent to your code
//-----------------------------
class User {
    public function images() {
        return $this->belongsToMany(Image::class)->withPivot('vote');
    }
}

Open in new window


On the Vitrine Model I coded:

public function users() {
	return $this->belongsToMany(User::class)->withPivot('user_vitrines');
}

//------------------------------
//Correspondent to your code
//-----------------------------
class Image {
    public function users() {
        return $this->belongsToMany(User::class)->withPivot('vote');
    }

Open in new window


On the UserVitrine Model I didn't code.

At VitrinesController (where on the last question the information "curtiu" is obtained)

//--------------------
// Code last question
//--------------------
$vitrinesX = Vitrine
	::vigente()
	->ativa()
	->aprovada()
	->global([0])
	->orderBy('id','desc')
	 ->withCount([
			'user_vitrines as qtdeCurtiu' => function (Builder $query) { $query->where('curtiu', 1); },
			//'user_vitrines as dislikes' => function (Builder $query) { $query->where('curtiu', 0); }
		])
		->get();

//-------------
// Added now
//-------------
$images = Vitrine::with('users')->get()
->each(function($vitrine) {
	$image->curtiu= $image->users->pluck('id');
});

//---------------------------------------
//  Correspondent to your code
//---------------------------------------
$images = Image::with('members')->get()
    ->each(function($image) {
        $image->votedBy = $image->members->pluck('id');
    });
//-------------------------------------------------------------------------------

// This returns to Vitrine view
return view('vitrines.index',compact('vitrinesX', 'images', 'vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'));

Open in new window



I'm certainly misconcepting something since this error arises:
img002
Could you check?
Most Valuable Expert 2018
Distinguished Expert 2018
Hi Eduardo,

Couple of issue with your code. When we call withPivot, we need to specify the column name from the Pivot table, so in your case, that's 'curtiu', so:

//User Model
public function vitrines() {
    return $this->belongsToMany(Vitrines::class)->withPivot('curtiu');
} 

//Vitrine Model
public function users() {
    return $this->belongsToMany(User::class)->withPivot('curtiu');
}

Open in new window

Eduardo FuerteDeveloper and Analyst

Author

Commented:
Adjusted

This code must to be adapted also:
img004
// line 97
    $images = Vitrine::with('users')->get()
        ->each(function($vitrine) {
            $image->curtiu = $image->users->pluck('id');
        });
     

Open in new window


Since this error occurs:
Most Valuable Expert 2018
Distinguished Expert 2018
Hey Eduardo,

Inside your closure, you're passing in a variable called $vitrine, but then you're trying to use a variable called $image. Change that to $vitrine

$vitrine->curtui = $vitrine->users->pluck('id');
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi  Chris

So did I:

        $images = Vitrine::with('users')->get()
        ->each(function($vitrine) {
            $vitrine->curtiu = $vitrine->users->pluck('id');
        });

Open in new window


But the SQL error table not found remains ...

The model UserVitrines doesn't received any method... isn't it necessary?
Most Valuable Expert 2018
Distinguished Expert 2018
Hey Eduardo,

It looks like you've named your SQL table incorrectly. Normally, when we create a many-to-many relationship. Laravel expects the pivot table to be named model_model (singular not plural). It also expects this table to be named from the 2 models it links in alphabetical order, so in your case you have 2 models - User and Vitrine. The pivot table to link these 2 together should be called user_vitrine. In your schema diagram, it looks like it's called user_vitrines (with an s on the end), which is why Laravel can't find it.

You also mention having a UserVitrines model. How dod you create that Model, because normally, if you want to use a Custom Pivot class, you need to extend the Pivot class (not the Model) and make sure you're relationship are using that.
Most Valuable Expert 2018
Distinguished Expert 2018
If you really don't want to use the standard names for your pivot table (I would suggest you do), then you can pass a second argument to the belongsToMany() method:

public function vitrines() {
    return $this->belongsToMany(Vitrines::class, 'user_vitrines')->withPivot('curtiu');
}
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Going the 1st way, renaming to user_vitrine:


// That start runs      
$images = Vitrine::with('users')->get()
->each(function($vitrine) {
	$vitrine->curtiu = $vitrine->users->pluck('id');
});

//Obtains data
dd($images)

Open in new window



// But this that was OK starts with error      

$vitrinesX = Vitrine
::vigente()
->ativa()
->aprovada()
->global(Auth::user()->tipoparticipante_id)
->orderBy('id','desc')
 ->withCount([
		'user_vitrines as qtdeCurtiu' => function (Builder $query) { $query->where('curtiu', 1); },
		'user_vitrines as dislikes' => function (Builder $query) { $query->where('curtiu', 0); }
	])
	->get();

Open in new window


So I guess something must to be adjusted on the Models to adapt it to the to the new table name, isn't it?


Going the 2nd way:

Returning back to the previous table name:
rename table user_vitrine to user_vitrines

Open in new window



Adjusted on the model User
   public function vitrines() {
    return $this->belongsToMany(Vitrines::class, 'user_vitrines')->withPivot('curtiu');
}   

Open in new window


The 02 Controller codes started going with error....

And I saw that renaming the table to user_vitrine brokes another parts of the code  - on the Model UserVitrine, really intricated....


If necessary the Models code just sinalize, please.
Most Valuable Expert 2018
Distinguished Expert 2018
OK.

Let's take a step back a see if we can figure out what's going on. You should have 2 models - User and Vitrine. These 2 models have database tables called users and vitrines. You also have a 3rd table called user_vitrine - this is the pivot table to link the many-to-many relationship between User and Vitrine (no need for a Model at this point). That table has fields called user_id and vitrine_id, plus an additional column called curtiu.

On your User model, you define the relationship to the many Vitrine objects like so:

public function vitrines() {
    return $this->belongsToMany(Vitrine::class)->withPivot('curtiu');
}

Open in new window

And on the Vitrine model, you define the inverse relationship like so:

public function users() {
    return $this->belongsToMany(User::class)->withPivot('curtiu');
}

Open in new window


That's the basics of setting up a many-to-many relationship. That's all you need for that to work.

Now in your controller, when you want to see which users have liked (or disliked) an image, you can do the following:

$images = Vitrine::with('users')->get()
    ->each(function($vitrine) {
        $vitrine->curtiu = $vitrine->users->pluck('id');
    });

Open in new window

That will retrieve a list of Images ($images). Each Image will have a property called curtiu that contains a collection of UserId (Users that have liked an image).

If you want to get a count of the likes and dislikes, then you can call withCount against the Relationship property (users on Vitrine), so something like this:

$images = Vitrine::with('users')
    ->withCount([
        'users as likes' => function (Builder $query) { $query->where('curtiu', 1); },
        'users as dislikes' => function (Builder $query) { $query->where('curtiu', 0); }
    ])
    ->get();

Open in new window

That will retrieve a list of Images ($images). Each image will have 2 new properties called likes and dislikes that contain the number of likes ('curtiu' = 1) and dislikes ('curtiu' = 1) from the pivot table.

You can now string those 2 things together in your controller, so something like this:

$images = Vitrine::with('users')
    ->withCount([
        'users as likes' => function (Builder $query) { $query->where('curtiu', 1); },
        'users as dislikes' => function (Builder $query) { $query->where('curtiu', 0); }
    ])
    ->get()
    ->each(function($vitrine) {
        $vitrine->curtiu = $vitrine->users->pluck('id');
    });

Open in new window

That will retreive a list of Images ($images). Each image will have 3 extra properties - likes (containing the number of likes), dislikes (containing the number of dislikes) and curtiu (containing a list of UserIds that have liked or disliked the image).
Eduardo FuerteDeveloper and Analyst

Author

Commented:
I'm going to check all the points above.

But just one thing I did that eliminated the errors:

Maintained as before:

User Model
   public function vitrines() {
        return $this->belongsToMany(Vitrines::class)->withPivot('curtiu');
    }

Open in new window


Vitrine Model  Adjusted to:
    public function users() {
        //return $this->belongsToMany(User::class)->withPivot('curtiu');
        return $this->belongsToMany(User::class, 'user_vitrines')->withPivot('curtiu');    
    }

Open in new window



Controller code:

           $vitrinesX = Vitrine
                ::vigente()
                ->ativa()
                ->aprovada()
                ->global(Auth::user()->tipoparticipante_id)
                ->orderBy('id','desc')
                 ->withCount([

//--- changed to user_vitrine  (from users_vitrine)
                        'user_vitrine as qtdeCurtiu' => function (Builder $query) { $query->where('curtiu', 1); },
                        //'user_vitrines as dislikes' => function (Builder $query) { $query->where('curtiu', 0); }
                    ])
                    ->get();
                    
                    
                    
                // EF 2020
                $images = Vitrine::with('users')->get()
                ->each(function($vitrine) {
                    $vitrine->curtiu = $vitrine->users->pluck('id');
                });

Open in new window



Opening the view $images is presented with dd

Does it makes any sense?
Most Valuable Expert 2018
Distinguished Expert 2018
Hey Eduardo,

In your User model you have this:

public function vitrines() {
    return $this->belongsToMany(Vitrines::class)->withPivot('curtiu');
}

I thought your model was called Vitrine (no s).

In this line: 'user_vitrine as qtdeCurtiu' => function (Builder $query)

user_vitrine refers to the name of your Relationship method on your Vitrine class. In my example above, I just called it users():

public function users() {
    return $this->belongsToMany(User::class)->withPivot('curtiu');
}

It's up to you what you call it, but make sure that whatever you do call it, you use in the controller.

It now sounds like you might have 2 different methods on your Vitrine model - one called users() and one called user_vitrine(). Are they not doing the same thing - getting the related User models?
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi Chris


I thought your model was called Vitrine (no s).
=> Yes


In your User model you have this:

public function vitrines() {
    return $this->belongsToMany(Vitrines::class)->withPivot('curtiu');
}

=> Yes
Most Valuable Expert 2018
Distinguished Expert 2018
OK, so this is wrong:

public function vitrines() {
    return $this->belongsToMany(Vitrines::class)->withPivot('curtiu');
}

You shouldnt add the s to Vitrines::class, It should be:

public function vitrines() {
    return $this->belongsToMany(Vitrine::class)->withPivot('curtiu');
}
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Vitrine Model

    //public function user_vitrines() {

 // Used before at the last question... (and stays)
    public function user_vitrine() {
        return $this->hasMany('App\Models\UserVitrine');
    }
    
    public function users() {
        //return $this->belongsToMany(User::class)->withPivot('curtiu');
        return $this->belongsToMany(User::class, 'user_vitrines')->withPivot('curtiu');    
    }

Open in new window

Eduardo FuerteDeveloper and Analyst

Author

Commented:
Chris


Could you check my code?

Hard to follow what's the correct version...
Most Valuable Expert 2018
Distinguished Expert 2018
Hmmm. Maybe I'm missing something as I'm a little confused about your Relationships.

Is this correct. You have Users on your system and you have Vitrines on your system. A user can like many Vitrines, and a Vitrine can be liked by many Users?

If that is correct, then that's a many-to-many relationship, linked by a pivot table and modeled by the belongsToMany() methods.

What is the UserVitrine model used for? As you have it, each single Vitrine can have many UserVitrines, but I don't understand what that model is for.
Most Valuable Expert 2018
Distinguished Expert 2018
It's my understanding that you should have 2 models (User / Vitrine). These 2 models each have their own db table (users / vitrines). There is also a 3rd table called user_vitrine which links to 2 tables together (called a pivot table), but there is no need for a 3rd model called UserVitrine. Your User model links to the many Vitrine models by using the belongsToMany() method and your Vitrine model links to the many User models by using the belongsToMany() method.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Users (Authenticatable)

<?php

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

use App\Notifications\RedefinirSenha;

class User extends Authenticatable
{
    use HasApiTokens,Notifiable;

}

Open in new window

Eduardo FuerteDeveloper and Analyst

Author

Commented:
The model actualized:

img007
Eduardo FuerteDeveloper and Analyst

Author

Commented:
The correct pages names:

img008
Most Valuable Expert 2018
Distinguished Expert 2018
OK.

That makes sense. Looking at your schema, you have the DB pivot table now correctly named - user_vitrine. That is correct.

In your User model, you have a method called vitrines() - this is correct.

In your Vitrine model, you have a method called users() - delete that.

In your Vitrine model, you have a method called user_vitrine() - this is correct

You have a model called UserVitrine - delete that.

Now, in your Controller, you need the following:

if (Auth::check()){
    $vitrinesX = Vitrine
        ::with('user_vitrine')
            ->vigente()
            ->ativa()
            ->aprovada()
            ->global(Auth::user()->tipoparticipante_id)
            ->orderBy('id','desc')
            ->withCount([
                'user_vitrine as likes' => function (Builder $query) { $query->where('curtiu', 1); },
                'user_vitrine as dislikes' => function (Builder $query) { $query->where('curtiu', 0); }
            ])
            ->get()
            ->each(function($vitrine) {
                $vitrine->liked_by= $vitrine->user_vitrine->pluck('id');
            });

Open in new window

Now you will have a variable called $vitrinesX that contains a collection of Vitrine objects. Each of these Vitrine objects will have 3 additonal properties - likes, dislikes and liked_by.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Sorry

I had to reconsider UserVitrine, because the VitrinesController is calling it:


    $mUserVitrine = new UserVitrine();
        $qtdeCurtiu = 0;
        $qtdeNaoCurtiu = 0;
        
        $userVitrine = null;
      
        if(!empty($vitrine)){
          $qtdeCurtiu = $mUserVitrine->obterCurtidasPorVitrine($vitrine->id, 1);
          $qtdeNaoCurtiu = $mUserVitrine->obterCurtidasPorVitrine($vitrine->id, 0);

          $userVitrine = $mUserVitrine->obter(Auth::user()->id, $vitrine->id);
        } else {
          $qtdeCurtiu = $mUserVitrine->obterCurtidasPorVitrine($vitrinesX[0]->id, 1);
          $qtdeNaoCurtiu = $mUserVitrine->obterCurtidasPorVitrine($vitrinesX[0]->id, 0);

          $userVitrine = $mUserVitrine->obter(Auth::user()->id, $vitrinesX[0]->id);
        }
        $curtiu = !empty($userVitrine) ? $userVitrine->curtiu : "";
        
        
   
       
        //return view('vitrines.index',compact('vitrinesX','vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'));
        
        return view('vitrines.index',compact('vitrinesX', 'images', 'vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'));
    }

Open in new window

Eduardo FuerteDeveloper and Analyst

Author

Commented:
And when called this error arises:
 img009
Eduardo FuerteDeveloper and Analyst

Author

Commented:
And when saving a like

VitrinesController

  public function salvarEscolha(Request $request){

      $vitrine_id = $request->input('vitrine_id');
      $curtiu = $request->input('curtiu');

info($vitrine_id);
info($curtiu);

      $mUserVitrine = new UserVitrine();
   
      $userVitrine = $mUserVitrine->obter(Auth::user()->id, $vitrine_id);


      if(empty($userVitrine)){
        $userVitrine = new UserVitrine();
        $userVitrine->user_id = Auth::user()->id;
        $userVitrine->vitrine_id = $vitrine_id;
        $userVitrine->created_at = Carbon::now();
      }

      $userVitrine->curtiu = $curtiu;
      $userVitrine->updated_at = Carbon::now();
      $userVitrine->save();

      return response()->json(new Resultado(true, 'Sucesso', null), 200);
    }

Open in new window


A similar error occurs since the table user_vitrines isn't found.
img010
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Chris


This part could be easily eliminated since it was part of an old code:

//        $mUserVitrine = new UserVitrine();
//        $qtdeCurtiu = 0;
//        $qtdeNaoCurtiu = 0;
//        
//        $userVitrine = null;
//      
//        if(!empty($vitrine)){
//          $qtdeCurtiu = $mUserVitrine->obterCurtidasPorVitrine($vitrine->id, 1);
//          $qtdeNaoCurtiu = $mUserVitrine->obterCurtidasPorVitrine($vitrine->id, 0);
//
//          $userVitrine = $mUserVitrine->obter(Auth::user()->id, $vitrine->id);
//        } else {
//          $qtdeCurtiu = $mUserVitrine->obterCurtidasPorVitrine($vitrinesX[0]->id, 1);
//          $qtdeNaoCurtiu = $mUserVitrine->obterCurtidasPorVitrine($vitrinesX[0]->id, 0);
//
//          $userVitrine = $mUserVitrine->obter(Auth::user()->id, $vitrinesX[0]->id);
//        }
//        $curtiu = !empty($userVitrine) ? $userVitrine->curtiu : "";
        
// Just maintaining it for view's compatibility:
        $curtiu = 0;

Open in new window




But on the method  salvarEscolha above the data must to be saved at the table user_vitrine - I don't know how to change it, since it still looking for the table user_vitrines.
Most Valuable Expert 2018
Distinguished Expert 2018
Hi Eduardo,

When we're adding new records to Pivot tables, we tend to use the attach(), detach() and sync() methods. For your save method, you'd do something like this:

public function salvarEscolha(Request $request) {

    $vitrine_id = $request->vitrine_id;
    $curtiu = $request->curtiu;

    Auth::user()->vitrines()->sync(array($vitrine_id => array('curtiu' => $curtiu)), false);

    return response()->json(new Resultado(true, 'Sucesso', null), 200);
}

Open in new window

That will automatically insert or update a record from your pivot table.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Chris

So did I

    public function salvarEscolha(Request $request) {
    
        $vitrine_id = $request->vitrine_id;
        $curtiu = $request->curtiu;
        
        info('xxx');
        info($vitrine_id);
        info($curtiu);
        
    
        Auth::user()->vitrines()->sync(array($vitrine_id => array('curtiu' => $curtiu)), false);
    
        return response()->json(new Resultado(true, 'Sucesso', null), 200);
    }

Open in new window


With this error:

img011
It is is due:
App\Models\Vitrine.php
    public function vitrines() {
        return $this->belongsToMany(Models\Vitrine::class)->withPivot('curtiu');
    } 

Open in new window


No error...

And data created at DB:

select * from user_vitrine order by id desc

Open in new window


img012
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Chris


It looks everything is fine....what a fight!
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Chris

Thank you very much for another outstanding (hard and didactic) solution!!!
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Since this question assumed  a high degree of difficulty,  I'm going to open another question for the 2nd part.
Most Valuable Expert 2018
Distinguished Expert 2018
Hey Eduardo,

Glad we got there in the end. I think the problems with this question were largely down to how you were managing your Relationships. Once the Models and relationships (along with the DB tables) were in place correctly, it all started to make more sense.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
I agree with you.
Laravel Eloquent demands time and efforts to know its tricks.
It's not always intuitive. A lot of details you informed demands a lot of experience, no easily one with little experience could go to solve it in low time.