Tuesday, March 7, 2017

Laravel 5 Eloquent searching in relationship doesn't work

im trying to make a searchfield that returns records that are equal to the search result. I have 2 models, Brands and Cars. My relationship is that a brand(Opel, Suzuki etc.) has many cars and a brand belongs to a car.

Brand Model

class Brand extends Model
{
   protected $fillable = [
    'brandname'
   ];
   public function cars(){
      return $this->hasMany(Car::class);
   }

}

Cars Model

class Car extends Model
{
    public function brand(){
       return $this->belongsTo(Brand::class);
    }
    protected $fillable = [
       'user_id', 'brand_id', 'year', 'licensplate'
    ];
}

I have a page that shows all the cars with some information. Find Cars form

This is de code of the page:

<div class="col-sm-8 blog-main">
    <h1>Alle auto's</h1><hr>
    <form method="POST" action="/allcars">
        
        <div class="form-group">
            <input type="text" name="searchfield" placeholder="Merk">
            <button type="submit">Zoek</button>
        </div>
    </form>
    @foreach($brands as $brand)
            @foreach($brand->cars as $car)
                <div class="form-group">
                    <h5>
                        
                    </h5>
                    Kenteken: <br>
                    Bouwjaar: <br>
                </div>
            @endforeach
    @endforeach
</div>

This is my route file:
Routes

 Route::post('/allcars', 'CarController@show');

Finally my controller file: CarController.php

public function show(){
    $input = request('searchfield');
    if(empty($input))
    {
        return back();
    }

    else if(is_numeric($input))
    {
      // Search on year
      $brands = Brand::with('cars')->whereHas('cars', function($q)
        {
            $input = request('searchfield');
            $q->where('year', $input);
        })->get();
        return view('content.cars.index', compact('brands'));
    }
    else
    {
        // Search on brandname
        $brands = Brand::with('cars')->get()->where('brandname', $input);
        return view('content.cars.index', compact('brands'));
    }
}

The else if statement is working perfectly. When an integer (year) is being filled in it uses the year search and when a string is filled in it uses the brand search.

However, the brand search is working perfectly. If I search on 'Opel', i get all the cars with some information that are from the brand Opel. But when I search on 1990, I get a brand that has a car with the year 1990, and then i get the other cars from that brand as well.

Example:

If I search for 1990, I get 3 cars: Opel(1990), Opel(2000) and Opel(1882).

An other example: I search on 2000, I get 5 cars: Opel(2000), Opel(1990), Opel(1882), BMW(2000), BMW(1721).

I think I am doing something wrong in my code, please correct me. These are my migrations btw: Car Migration

Schema::create('cars', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('user_id');
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->unsignedInteger('brand_id');
        $table->foreign('brand_id')->references('id')->on('brands')->onDelete('cascade');
        $table->string('year');
        $table->string('licensplate');
        $table->timestamps();
    });

Brand Migration

   Schema::create('brands', function (Blueprint $table) {
        $table->increments('id');
        $table->string('brandname');
        $table->timestamps();
    });



via Koen van de Sande

Advertisement