0
votes

I'm struggling with this functionality in Laravel 5.5 for a week, so guys please help me to solve this issue.

In my database I have these tables:

categories - id, created_at, updated_at

categories_translations id, category_id, locale, user_id, name, slug, created_at, updated_at

teams - id, created_at, updated_at

teams_translations - id, team_id, locale, title, slug, image, body, created_at, updated_at

I'm using Laravel translatable 3rd-party from here: https://github.com/dimsav/laravel-translatable

So far I've created relationship successfully with these tables and in my admin section I'm showing created teams with related categories. Also on frontpage I'm showing all teams in one page list. When I click on specific team, it shows the team page. That's great.

I'm struggling with showing teams by categories.

So, this is my code.

Category model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Dimsav\Translatable\Translatable;

class Category extends Model
{
    use Translatable;

    public $translatedAttributes = ['name', 'slug', 'status', 'user_id', 'image', 'locale'];

    public function teams()
    {
        return $this->hasMany(Team::class);
    } 
}

CategoryTranslation model:

<?php

namespace App;

use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;

class CategoryTranslation extends Model
{
  use Sluggable;

  protected $touches = ['category'];
  public $timestamps = false;

  /**
   * Return the sluggable configuration array for this model.
   *
   * @return array
   */
  public function sluggable()
  {
      return [
          'slug' => [
              'source' => 'name',
              'onUpdate' => true
          ]
      ];
  }

  public function category() {
    return $this->belongsTo('App\Category');
  }
}

Team model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Dimsav\Translatable\Translatable;

class Team extends Model
{
    use Translatable;

    public $translatedAttributes = ['title', 'slug', 'body', 'status', 'user_id', 'image', 'category_id', 'locale'];

    public function category() {
       return $this->belongsTo(Category::class);
    }
}

TeamTranslation model:

<?php

namespace App;

use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;

class TeamTranslation extends Model
{
    use Sluggable;

    protected $touches = ['team'];
    public $timestamps = false;

    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable()
    {
        return [
            'slug' => [
                'source' => 'title',
                'onUpdate' => true,
            ]
        ];
    }

    public function team() {
      return $this->belongsTo(Team::class);
    }
}

Part of my route:

Route::get('/team/category/{category}', ['uses' => 'TeamController@teamCategory', 'as' => 'teamCategory']);

Part of my TeamController:

public function teamCategory(Category $category) {

  return $category;
}

And here is my view:

@extends('layouts.frontend')

@section('title', __('t.team'))

@section('content')
  <div class="main team-list">
    <div class="container">
      <div class="col-md-3">
        <ul>
          @foreach($categories as $category)
            <li><a href="{{ route('teamCategory', $category->slug) }}">{{ $category->name }}</a></li>
          @endforeach
        </ul>
      </div>
      <div class="col-md-9">
        @foreach($teams as $team)
          @if($team->status == 1)
            <div class="row">
              <div class="image">
                <a href="{{ route('team.team', $team->slug) }}"><img width="120" src="{{ Storage::url($team->image) }}" ></a>
              </div>
              <div class="title">
                {{ $team->title }}
              </div>
              <div class="body">
                {!! str_limit($team->body, 300) !!}
              </div>
              <div class="category">
                  {{ $team->category ? $team->category->name : 'No category' }}
              </div>
              <a class="more">More</a>
            </div>
          @endif
        @endforeach
      </div>
    </div>
  </div>
@endsection

For a example I have a category name php, so in the view when I click on the category link, it goes to this url: mywebsite.com/en/team/category/php and it shows:

Sorry, the page you are looking for could not be found.

I've tried to add this method in the Category model:

public function getRouteKeyName() {
      return 'slug';
    }

and it shows:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'slug' in 'where clause' (SQL: select * from `categories` where `slug` = php limit 1)

Later I've tried with this too:

public function getRouteKeyName() {
          return 'name';
        }

but it shows this:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name' in 'where clause' (SQL: select * from `categories` where `name` = php limit 1)

Anyone help?

EDIT:

I've tried Nikola's answer like this:

CategoryTranslation model:

<?php

namespace App;

use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;

class CategoryTranslation extends Model
{
  use Sluggable;

  protected $touches = ['category'];
  public $timestamps = false;

  /**
   * Return the sluggable configuration array for this model.
   *
   * @return array
   */
  public function sluggable()
  {
      return [
          'slug' => [
              'source' => 'category.slug',
              'onUpdate' => true
          ]
      ];
  }

  public function category() {
    return $this->belongsTo(Category::class);
  }
}

TeamTranslation model:

<?php

namespace App;

use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;

class TeamTranslation extends Model
{
    use Sluggable;

    protected $touches = ['team'];
    public $timestamps = false;

    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable()
    {
        return [
            'slug' => [
                'source' => 'team.slug',
                'onUpdate' => true,
            ]
        ];
    }

    public function team() {
      return $this->belongsTo(Team::class);
    }
}

but it shows the same error.

1
Can you give us html too? - Nikola Gavric
Hi, Nikola. I've added the view. - user2519032
Based off of their official docs, source represents the actual attribute you are using to store the slug, and it can be used with a dot notation, which means it supports relationships, so since you have relationships in your translate models, category.slug and team.slug are valid sources - Nikola Gavric

1 Answers

0
votes

Try with updating your 2 sluggable methods in your translate classes to these:

CategoryTranslation.php

/**
 * Return the sluggable configuration array for this model.
 *
 * @return array
 */
  public function sluggable()
  {
    return [
        'slug' => [
            'source' => 'category.slug',
            'onUpdate' => true
        ]
    ];
  }

TeamTranslation.php

/**
 * Return the sluggable configuration array for this model.
 *
 * @return array
 */
  public function sluggable()
  {
    return [
        'slug' => [
            'source' => 'team.slug',
            'onUpdate' => true
        ]
    ];
  }

The above code is based on official docs and should be working with your implementation

EDIT: I've just noticed you are fetching the wrong entity from your controller, try using this code instead

public function teamCategory(CategoryTranslation $category) {

  return $category;
}