Relationship with 3 tables in Standard

Asked

Viewed 1,954 times

2

I’m trying to make the relationship between three tables in the Latvian. With 2 tables I managed, thanks to the help of the forum, but I’m not able to make it work with 3 tables. the relationship is as follows: I have 3 tables:

News, Photos and Unit (school units)

tabela noticia -> id_noticias

tabela fotos-> id_fotos e id_noticias

tabela noticia_unidade

The relationship news with photos is ok: on the main page appear 2 news and a picture of each. Now I need it to be filtered by unit: On the college page appear only the news from unit 2, for example.

Follow the Models and Controllers:

Controller

public function index(){
    $not_faculdade = Noticia::with(['foto' => function($query){
        $query->get()->first();
        }])
    ->with(['unidade' => function($query2){
            $query2->where('id_unidade','2')->get();
        }])
    ->orderBy('id_noticias','DESC')
    ->take(2)
    ->get();
    // dd($not_faculdade);
    return view('pages_faculdade.noticia')->with('not_faculdade',$not_faculdade);
}

Models

class Noticia extends Model
{
    protected $table = 'noticias';
    protected $primaryKey = 'id_noticias';
    public $timestamps = false;
    protected $dates = ['data'];
    protected $fillable =[
            'texto',
            'titulo',
            'legenda',
            'pasta',
            'subtitulo',
            'evento',
            'titulo_evento'
    ]; 

    public function foto()
    {
        //return $this->hasMany(Foto::class); 
        return $this->hasMany('App\Foto','id_noticia','id_noticias'); 
    }

    public function unidade()
    {
        //return $this->hasMany(Foto::class); 
        return $this->belongsTo('App\Unidade','id_noticias','id_noticia'); 
    }    
}

class Unidade extends Model
{
    protected $table = 'noticia_unidade';
    //  protected $primaryKey = 'id_noticia, id_unidade';
    public $timestamps = false;
    protected $dates = ['deleted_at'];
    protected $fillable = [
        'id_unidade',
        'id_noticia'
    ];

    public function noticias()
    {
        return $this->hasMany('App\Noticia','id_noticias','id_noticia'); 
    }
}

View

@foreach ($not_faculdade as $key=> $not)
    <div class="col-md-6">
        <div class="panel-heading">
            <div class="painel_foto"><img src={{asset('public/'.$not->foto[0]->endereco)}}></div>
            <h4>{{ $not->titulo }}</h4>
            <p align="justify">
                <a href="#" class="noticia">
                {{$texto = substr($not->texto,0,150)." ..."}}
                </a>
            </p>
        </div>
    </div> 
@endforeach

As I said, the 2 news with the "cover" photo usually appear, but the filter does not work. If I give a dd($not_faculdade), is shown the apparently right relationships!

What could be wrong?

Follow relationship (I did it the way I could because I don’t know how to work with these tools)

inserir a descrição da imagem aqui 1 news owns several photos belonging to a single news 1 news can appear in multiple units and each unit can contain various news

  • What happens? Not filtering by ID unit 2?

  • It’s not! Return all news, no filter!

  • Aren’t the relationships wrong? if you could put in your question the 3 tables and their relationships (the diagram of these three tables with relation would be sufficient)?

  • @Virgilionovic, I tried to draw the diagram, but I can’t use the tools to do it.

  • Cool relationship is. Many.para many between drive and news is wrong relationships but beyond said what intended, bring the news that???

  • I intend to bring the news regarding each unit. For example: The college is unit 2, the college is unit 3... then bring on the college page all the news that are unit 2.... and they’re all showing up, unfiltered...

  • Got it @Giselepassoni but, I’m going to put on how relationships should be for it to work! OK?

  • 1

    Okay, @Virgilionovic

Show 3 more comments

2 answers

1

There are problems in your relationships through settings on Model of their classes, then, I will propose a minimum model so that I can do in your project, example:

Diagram:

inserir a descrição da imagem aqui

Classes

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Noticia extends Model
{
    protected $fillable = ['titulo', 'texto'];
    protected $primaryKey = 'id_noticia';

    public function unidades()
    {
        return $this->belongsToMany(Unidade::class,
            'noticia_unidade',
            'id_noticia',
            'id_unidade');
    }
    //para trazer todas as fotos
    public function fotos()
    {
        return $this->hasMany(Foto::class, 'id_noticias', 'id_noticia');
    }
    // para trazer 1 foto
    public function foto()
    {
        return $this->hasOne(Foto::class, 'id_noticias', 'id_noticia');
    }
}

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Unidade extends Model
{
    protected $fillable = ['titulo'];
    protected $primaryKey = 'id_unidade';

    public function noticias()
    {
        return $this->belongsToMany(Noticia::class,
            'noticia_unidade',
            'id_unidade',
            'id_noticia');
    }
}

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Foto extends Model
{
    protected $fillable = ['id_noticias', 'foto'];
    protected $primaryKey = 'id_fotos';

    public function noticia()
    {
        return $this->belongsTo(Noticia::class, 'id_noticias', 'id_noticia');
    }
}

How to use?

 App\Noticia::with('foto')
     ->whereHas('unidades', function($q){
         $q->where('noticia_unidade.id_unidade',2);
     })
     ->get();

Upshot

=> Illuminate\Database\Eloquent\Collection {#724
     all: [
       App\Noticia {#734
         id_noticia: 1,
         titulo: "Noticia 1",
         texto: "Texto 1",
         foto: App\Foto {#746
           id_fotos: 1,
           id_noticias: 1,
           foto: "foto/0001-1.jpg",
         },
       },
       App\Noticia {#716
         id_noticia: 2,
         titulo: "Noticia 2",
         texto: "Texto 2",
         foto: App\Foto {#747
           id_fotos: 2,
           id_noticias: 2,
           foto: "foto/0002-1.jpg",
         },
       },
     ],
   }

Explanation: in the table the news number 3 is not part of unit 2 so it does not appear. Another point that in the class Noticia two methods were created foto and fotos, where respectively brings only one photo and the other all base photos, this is good to optimize the SQL.


Observing: check all fields, names, classes, etc.., this can cause errors due to incorrect configuration or configuration. Another point is that you should have used the standard nomenclature, but no problem if you don’t use it, only in this aspect you should configure, model for model.

  • I did as directed and this error appeared: Queryexception in Connection.php line 647: SQLSTATE[42000]: Syntax error or access Violation: 1066 Not Unique table/alias: 'noticia_drive' (SQL: select * from noticias Where exists (select * from noticia_unidade Inner Join noticia_unidade on noticia_unidade.id_unidade = noticia_unidade.id_unidade Where noticias.id_noticias = noticia_unidade.id_noticia and noticia_unidade.id_unidade = 2))

  • @Giselepassoni if you didn’t, you’re doing the SQL wrong is what I said is some configuration missing, it’s something simple, because it can’t in that case make a Join Inner for itself... Must be configuration in the model! take a look and edit your question and put what changed!

  • @Giselepassoni looks like it would SQL: "select * from newswhere exists (select * fromunitsinner joinnoticia_unidadeonunits.id_unity=noticia_unidade.id_ unitwherenews.id_noticia=noticia_unidade.id_noticiaandnoticia_unidade.id_unity = ?)" generated by my example!

  • Sorry, I’m having to learn how to develop our portal... all this is news to me. I will stir here until I get a solution!

  • @Giselepassoni does not need to apologize, but the community likes to help ... this is an exchange, what you have done now because the table is doing the wrong SQL and this is configuration! take a look at my models please and tell me! I’m here I can help you

  • After breaking my head, looking for where the error was, I was able to make it work, but I had to leave belongsTo instead of belongsToMany. For some reason I couldn’t figure out the pq, it wasn’t working...

  • @Giselepassoni has something very strange, well I followed his drawing, I would have to do a fine-tooth comb to know the reality of his project.

Show 2 more comments

0

I believe this will not work. You can use the whereHas in place of with.

$not_faculdade = Noticia::with(['foto' => function($query){
    $query->get()->first();
}])
->whereHas('unidade', function($query2){
    $query2->where('id_unidade','2');
})
->orderBy('id_noticias','DESC')
->take(2)
->get();
  • Okay, I’ll try it now! I’ve put it here if it worked!

  • This error message is showing: Parse error: syntax error, Unexpected '=>' (T_DOUBLE_ARROW), expecting ',' or ')' And says that it is on the line containing this code: ->whereHas('unit' => Function($query2){

  • @Giselepassoni tries to replace this line by: ->whereHas('unidade', function($query2){

  • @Juniornunes, I did that and the error is gone, but it still doesn’t filter the news by unit!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.