skip to Main Content

I’m new to laravel and try to make some simple test websites to get better.

I try to call a public procedure I’ve made in a model. The Idea is to put all the SQL Selects out of the code in the website.I’ve tried a lot and read a lot about it but what can I say. I’m lost at the moment.

My Model :

class Terroir extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'type',
        'terroir_id',
    ];

    public function Countries() {
        $countrys= Terroir::select(['name','id'])
        ->where ('type',1)
        ->wherenull('terroir_id')
        ->orderby('name','ASC')
        ->get();

        return($countrys);
    }
}

If I try to call it like that inside a PHP Tag :

$countrys=AppModelsTerroir::with('Countries');

But it didn’t reach the model.

This works inside the PHP-Code :

$countrys = AppModelsTerroir::select(['name','id'])
                            ->where ('type',1) 
                            ->wherenull ('terroir_id') 
                            ->orderby('name','ASC')
                            ->get();

So I hope I’m not totaly wrong to try to call a procedure inside the Model.

I think I need help how to call this simple procedure correctly (If it is possible anyway).

Best regards, Stephan

2

Answers


  1. Try using Local Scopes. Local Scopes

    class Terroir extends Model{
    
    use HasFactory;
    
    protected $fillable = [
        'name',
        'type',
        'terroir_id',
    ];
    
    public function scopeCountries(Builder $query): void {
         $query->select(['name','id'])
        ->where ('type',1)
        ->wherenull('terroir_id')
        ->orderby('name','ASC');
    
    } }
    

    Controller

    class TerroirController extends Controller{
    
        public function index()
    {
       
       $countries = AppModelsTerroir::countries()
                            ->get();
    
    } }
    
    Login or Signup to reply.
  2. Well for those who new to eloquent (laravel orm) i will always recommend to distinguish differences between query-builder, collection and model instance.

    Query builder:

    As the name says, you can make queries with it, you can create it with DB:: facade or with models as well.

    Example:

    AppModelsTerroir::select(['name','id'])
        ->where ('type',1) 
        ->wherenull ('terroir_id') 
        ->orderby('name','ASC');
    

    You need to know this is query builder and as long as keep chaning the query builder methods like where() it will stay a query builder. There are some methods you can call on query builder faze for example a method with prefix of scope or relationships can put into with() for eager loading. But for custo method or procedure you cant call it because you are not dealing with a single model instance its query builder.

    Collection:

    This is class like arrays for laravel that provides extra features. If you chain the ->get() method to query builder by default you will get a collection of models. Then you can iterate throw them. There are other methods to fetch the query and convert it to collection as well.

    Model instance:

    This is class like arrays for laravel that provides extra features. If you chain the ->first() method to query builder by default you will get a model instance. There are other methods to fetch the query and convert it to model instance as well.

    So for calling procedure because you dealing with model instance first you need get the model instance then you can call the method.

    And because of this the first code you wrote doesnt make sense because first you need to get a random model, then call the method. The second code if its working then i think its ok to use. But solutions for first code:

    1. Use a static procedure.(Im not quite fond of it)
    2. Use laravel standards like local-scopes https://laravel.com/docs/11.x/eloquent#local-scopes

    Code for first solution

    class Terroir extends Model {
    use HasFactory;
    
    protected $fillable = [
        'name',
        'type',
        'terroir_id',
    ];
    
    public static function countries() {
        return Terroir::select(['name','id'])
        ->where ('type',1)
        ->wherenull('terroir_id')
        ->orderby('name','ASC')
        ->get();
    }}
    

    Then you can call it like this:

    $countrys = AppModelsTerroir::countries();
    

    I recommend to read more about these in laravel docs.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search