Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

nitinvismaad's avatar

JOIN replaces the original id with the id of joined table in Laravel

I got four tables

  1. Links (id, user_id, link_data, category_id, submit_date)
  2. Users (id, username, password, status)
  3. Categories (id, name, slug)
  4. Tags (id, link_id, tags)

I want to show all link details with username, Category name & slug and tags but with join it replaces the links.id with the category.id.

$catid = Category::where('slug', '=', $slug)->firstOrFail()->id;

$linksbycategories = DB::table('links') ->where('category_id', '=',$catid) ->join('users', 'users.id', '=', 'links.user_id') ->join('categories', 'categories.id', '=', 'links.category_id') ->join('tags', 'tags.link_id', '=', 'links.id')->get(); return $linksbycategories; //return view('category', ['linksbycategories' => $linksbycategories]);

I have 3 tags of link id 1 and the result I get is 3 times data of first link information with link id as 7 which is the category id of that link. How can I solve this.

0 likes
13 replies
Snapey's avatar

using Eloquent gets around this problem of having colliding column names (it will happen for any column with the same name)

Using joins, you have to also consider using Selects and alias the columns with as just as you would with raw database queries.

https://laravel.com/docs/5.8/queries#selects

nitinvismaad's avatar

With using select I am getting this error.

"SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in field list is ambiguous (SQL: select `id` as `link_id`, `user_id` as `link_user_id`, `link` as `link_link`, `title` as `link_title`, `description` as `link_description`, `submitted_at`, `category_id` as `link_category_id`, `votes a link_votes` from `links` inner join `users` on `users`.`id` = `links`.`user_id` inner join `tags` on `tags`.`link_id` = `links`.`id` inner join `categories` on `categories`.`id` = `links`.`category_id` where `category_id` = 7)

this is the code

$linksbycategories = DB::table('links')
->select('id as link_id','user_id as link_user_id', 'link as link_link', 'title as link_title', 'description as link_description', 'submitted_at', 'category_id as link_category_id', 'votes a link_votes')
->where('category_id', '=',$catid)
->join('users', 'users.id', '=', 'links.user_id')
->join('tags', 'tags.link_id', '=', 'links.id')
->join('categories', 'categories.id', '=', 'links.category_id')->get();
Snapey's avatar

You need to specify the table name, eg

->select('links.id as link_id','links.user_id as link_user_id',

otherwise the columns are ambiguous, ie you say alias the id column, but the database does not know which of the three you mean

nitinvismaad's avatar

With table names the query worked but now the JOIN data won;t show

->join('users', 'users.id', '=', 'links.user_id')
->join('tags', 'tags.link_id', '=', 'links.id')
->join('categories', 'categories.id', '=', 'links.category_id')
Snapey's avatar

contrast with

$links = Links::whereHas('categories', $catid)
                 ->with(['categories','tags','users'])->get();
nitinvismaad's avatar
"Argument 2 passed to Illuminate\Database\Eloquent\Builder::whereHas() must be an instance of Closure or null, int given, called in D:\xampp\htdocs\bookmarking\vendor\laravel\framework\src\Illuminate\Support\Traits\ForwardsCalls.php on line 23

error on link

 public function whereHas($relation, Closure $callback = null, $operator = '>=', $count = 1)
Snapey's avatar

sorry, whereHas needs a callback to evaluate the column of categories

$links = Links::whereHas('categories', function ($query) use ($catid) {
                 $query->where('id', '$catid');
                 })->with(['categories','tags','users'])->get();
nitinvismaad's avatar

Error Call to undefined method App\Links::categories()

})->with(['categories','tags','users'])->get();

These are my table names, do we need to use Model names or something else?

geraintp's avatar

You need to define the categories relationship on your link Model.

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

nitinvismaad's avatar

I already have it in my Link Model

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

    public function Tag()
    {
        return $this->hasMany('App\Tag', 'link_id');
    }
    public function User()
    {
        return $this->hasOne('App\User','id','user_id');
    }

Category Model

public function Link()
    {
        return $this->hasMany('App\Link', 'category_id');
    }

Tag Model

public function Link()
    {
        return $this->belongsTo('App\Link', 'id');
    }

User Model

public function user()
    {
        return $this->hasOne(Profile::class);
    }
    
    public function Link()
    {
        return $this->hasMany('App\Link','id');
    }
Snapey's avatar

you need to use the relationship names.

Youwill find it less confusing in the long term if you stick with conventions.

Use capital letter for class names and camel case for method names

nitinvismaad's avatar

Thanks I'll remember it.

I got the code working with this

$linksbycategories = \App\Link::with('User','Category','Tags')
->whereHas('Category',function($q) use($slug){
$q->where('slug', '=', $slug);
})->get();

But now I am stuck with it's pagination.

{{$data->links()}}

won't work.

Snapey's avatar

because you have to use paginate and not get

$linksbycategories = \App\Link::with('User','Category','Tags')
->whereHas('Category',function($q) use($slug){
$q->where('slug', '=', $slug);
})->paginate();

Please or to participate in this conversation.