Ali.Wassouf
Ali.Wassouf

Reputation: 309

Laravel - Extending User model

I have a class Seller that extends laravel's User model as the following

namespace App; 
class Seller extends User{
   public function products(){
       return $this->hasMany(Products::class);
   }
}

in the ModelFactory.php I have the following code

$factory->define(Transaction::class, function (Faker\Generator $faker) {
  $seller = Seller::has('products')->get()->random();
  $buyer = User::all()->except($seller->id)->random();
  return [
    'quantity' => $faker->numberBetween(0, 3),
    'buyer_id' => $buyer->id,
    'product_id' => $seller->products->random()->id
 ];
});

I'm getting the following error

Base table or view not found: 1146 Table 'tutorial.sellers' doesn't exist (SQL: select * from sellers where exists (select * from products where sellers.id = products.seller_id))

the Product class is as the following

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model{
     const AVAILABLE_PRODUCT = 'available';
     const UNAVAILABLE_PRODUCT = 'unavailable';

     protected $fillable = [
         'name',
         'description',
         'quantity',
         'status',
         'image',
         'seller_id'
     ];

     public function isAvailable(){

         return $this->status == Product::AVAILABLE_PRODUCT;

     }

    public function seller(){

        return $this->belongsTo(Seller::class);

    }

    public function categories(){

        return $this->belongsToMany(Category::class);

    }

    public function transactions(){
        return $this->hasMany(Transaction::class);
    }

}

apparently, the generated query does not take the inheritance into consideration. I tried changing $seller = Seller::has('products')->get()->random(); into $seller = User::has('products')->get()->random(); but then the line 'product_id' => $seller->products->random()->id causes an error since the products() method is defined in seller class What's the best way to do this?

Is it a right way to extend User class ?

I have searched for ways to extend the User class. I found this question: Model Inheritance in Laravel didn't help me though.

I'm using Laravel 5.4.36, PHP 7.1.11

Upvotes: 3

Views: 7939

Answers (1)

Ohgodwhy
Ohgodwhy

Reputation: 50787

To summarize:

Laravel will use the Class Name as the table name if not explicitly declared on the model. This causes Laravel to automatically assume sellers as the table name in the query. To resolve this add the following to the extending Model:

protected $table = 'users'

Finally, you're attempting to use ->random() on a query builder instance, but that's not what you want. You want to use it on the collection. You can do any of the following:

$seller->products()->get()->random()->id;

The above will perform the query and retrieve all products, then get you a random item from the returned collection, then retrieve the ID. The better (more efficient) way, is to let the Query builder handle it:

$seller->products->inRandomOrder()->first()->id;

Upvotes: 8

Related Questions