Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Model Laravel Package

jenssegers/model

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require jenssegers/model
    

    Add the namespace to your composer.json autoload:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Jenssegers\\Model\\": "vendor/jenssegers/model/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Model: Extend Jenssegers\Model\Model in your model:

    use Jenssegers\Model\Model;
    
    class User extends Model
    {
        protected $fillable = ['name', 'email'];
        protected $hidden = ['password'];
    }
    
  3. Basic Usage:

    $user = new User(['name' => 'John', 'email' => 'john@example.com']);
    $user->save(); // Override with custom logic (e.g., API call)
    

First Use Case: API Integration

Replace Eloquent’s save() with a custom API call:

public function save(array $options = [])
{
    $response = Http::post('https://api.example.com/users', $this->toArray());
    $this->setAttributes($response->json());
    return $this;
}

Implementation Patterns

1. Attribute Handling

  • Fillable/Guarded: Enforce strict attribute assignment:
    $user = new User(['name' => 'John', 'email' => 'invalid']); // Fails if 'email' not in $fillable
    
  • Casting: Convert attributes on access:
    protected $casts = [
        'is_admin' => 'boolean',
        'created_at' => 'datetime:Y-m-d',
    ];
    
    Usage:
    $user->is_admin; // Returns boolean
    $user->created_at->format('d/m/Y'); // DateTime object
    

2. Accessors/Mutators

  • Dynamic Properties:
    public function getFullNameAttribute()
    {
        return "{$this->first_name} {$this->last_name}";
    }
    
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = bcrypt($value);
    }
    
  • Appending to JSON/Array:
    protected $appends = ['full_name', 'role'];
    $user->toArray(); // Includes 'full_name' and 'role'
    

3. Serialization

  • Hidden Attributes:
    protected $hidden = ['password', 'api_token'];
    $user->toJson(); // Excludes hidden fields
    
  • Custom Serialization: Override toArray() or toJson() for bespoke output:
    public function toArray()
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'metadata' => $this->getMetadata(),
        ];
    }
    

4. Relationships (Lightweight)

While not as feature-rich as Eloquent, you can simulate relationships:

public function posts()
{
    return collect($this->related('posts')->all());
}

protected function related($name)
{
    return new static($this->{"{$name}_data"});
}

5. Events

Leverage Laravel’s event system for model lifecycle hooks:

protected static function boot()
{
    static::saving(function ($model) {
        $model->updateTimestamps();
    });
}

Gotchas and Tips

Pitfalls

  1. No Query Builder:

    • This package does not include Eloquent’s query builder. Use raw SQL or a separate package (e.g., illuminate/database) for database operations.
    • Workaround: Manually construct queries or use a micro-ORM like cycle/orm.
  2. Mass Assignment:

    • Unlike Eloquent, fill() is not automatically available. Use $model->setAttributes($data) or manually assign:
      $user->setFillable(['name', 'email'])->fill(['name' => 'Jane']);
      
  3. Timestamps:

    • No automatic created_at/updated_at. Manually set or override:
      protected $dates = ['created_at', 'updated_at'];
      public function updateTimestamps()
      {
          $this->updated_at = now();
          if (!$this->exists) {
              $this->created_at = now();
          }
      }
      
  4. Relationships:

    • No built-in relationship methods (e.g., hasMany). Implement custom logic or use a separate package.

Debugging Tips

  1. Attribute Conflicts:

    • If an accessor/mutator conflicts with a fillable attribute, explicitly define the attribute in $fillable or use setRawAttributes() to bypass mutators:
      $user->setRawAttributes(['password' => 'plaintext'], true);
      
  2. Casting Issues:

    • Ensure casted attributes exist before access:
      if (isset($this->attributes['age'])) {
          $this->age; // Now casted
      }
      
  3. Hidden Attributes in Arrays:

    • Hidden attributes are only filtered in toArray()/toJson(). Use $model->getAttributes() to see all raw data.

Extension Points

  1. Custom Validation: Override validate() or use Laravel’s validator:

    public function validate(array $attributes)
    {
        return Validator::make($attributes, [
            'email' => 'required|email',
        ]);
    }
    
  2. API Resource Integration: Pair with laravel/framework's Illuminate\Http\Resources\JsonResource for API responses:

    public function toJson()
    {
        return new UserResource($this);
    }
    
  3. Soft Deletes: Implement manually or use a trait:

    trait SoftDeletes
    {
        protected $deletedAt = 'deleted_at';
        public function delete()
        {
            $this->deleted_at = now();
        }
    }
    
  4. Observers: Use Laravel’s observer pattern for model events:

    class UserObserver {
        public function saving(User $user) { /* ... */ }
    }
    

    Register in a service provider:

    Model::observe(UserObserver::class);
    

Performance Tips

  • Avoid Overloading: Heavy accessors/mutators can slow serialization. Cache computed properties:

    private $cachedFullName;
    public function getFullNameAttribute()
    {
        return $this->cachedFullName ??= "{$this->first_name} {$this->last_name}";
    }
    
  • Lazy Loading: Defer expensive operations (e.g., API calls) until needed:

    private $posts;
    public function getPostsAttribute()
    {
        return $this->posts ??= $this->fetchPostsFromApi();
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle