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

Eloquence Laravel Package

sofa/eloquence

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sofa/eloquence
    

    For individual extensions (e.g., Metable):

    composer require sofa/eloquence-metable
    
  2. Publish Config (if needed):

    php artisan vendor:publish --provider="Sofa\Eloquence\EloquenceServiceProvider"
    

    Check config/eloquence.php for extension-specific configurations (e.g., searchable drivers, metable storage).

  3. First Use Case:

    • Searchable: Add Searchable trait to a model and define searchable fields:

      use Sofa\Eloquence\Searchable\Searchable;
      
      class Post extends Model
      {
          use Searchable;
      
          protected $searchable = ['title', 'body'];
      }
      

      Query with:

      $results = Post::search('laravel')->get();
      
    • Validable: Add Validable trait and define rules:

      use Sofa\Eloquence\Validable\Validable;
      
      class User extends Model
      {
          use Validable;
      
          protected $rules = [
              'name' => 'required|min:3',
              'email' => 'required|email'
          ];
      }
      

      Validate on save:

      $user = new User(['name' => 'John', 'email' => 'invalid']);
      if ($user->validate()) {
          $user->save(); // Fails silently if invalid
      }
      
    • Metable: Store meta data dynamically:

      use Sofa\Eloquence\Metable\Metable;
      
      class Product extends Model
      {
          use Metable;
      }
      

      Set/get meta:

      $product->setMeta('price', 19.99);
      $price = $product->getMeta('price');
      

Where to Look First

  • Documentation: Extension-specific guides (e.g., Searchable).
  • Traits: Check app/Models/ for existing implementations to replicate patterns.
  • Config: config/eloquence.php for extension-specific settings (e.g., searchable.driver).

Implementation Patterns

Core Workflows

1. Searchable

  • Basic Search:
    $posts = Post::search('query')->get();
    
  • Advanced Search (with Searchable config):
    $posts = Post::search('query')
                 ->with(['author']) // Eager load relations
                 ->orderBy('published_at', 'desc')
                 ->get();
    
  • Custom Drivers: Override SearchableServiceProvider to integrate with Algolia/Meilisearch:
    // config/eloquence.php
    'searchable' => [
        'driver' => 'algolia',
        'options' => [
            'app_id' => env('ALGOLIA_APP_ID'),
            'api_key' => env('ALGOLIA_API_KEY'),
        ],
    ];
    

2. Validable

  • Inline Validation:
    $user = new User(['email' => 'invalid']);
    $user->validate(); // Returns bool
    $errors = $user->errors(); // Collection of errors
    
  • Mass Assignment + Validation:
    $data = ['name' => 'Test', 'email' => 'test@example.com'];
    $user = User::create($data); // Automatically validates
    
  • Custom Messages:
    protected $messages = [
        'name.required' => 'A name is required!',
    ];
    

3. Metable

  • Dynamic Meta Storage:
    $product->setMeta('tags', ['sale', 'new']);
    $tags = $product->getMeta('tags', []); // Default: []
    
  • JSON Serialization: Automatically serializes/deserializes meta data to JSON in the meta column.
  • Relation-Based Meta:
    $user->setMeta('profile', ['bio' => 'Hello'], 'Profile');
    

4. Mappable

  • Attribute Mapping:
    use Sofa\Eloquence\Mappable\Mappable;
    
    class Order extends Model
    {
        use Mappable;
    
        protected $mappable = [
            'total' => 'amount',
            'tax' => 'tax_rate',
        ];
    }
    
    Access mapped attributes:
    $order->total; // Returns $order->amount
    
  • Relation Mapping:
    protected $mappable = [
        'customer_name' => 'user.name',
    ];
    

5. Mutable/Mutator

  • Pipe-Based Mutators:
    use Sofa\Eloquence\Mutable\Mutable;
    
    class User extends Model
    {
        use Mutable;
    
        protected $mutable = [
            'email' => [
                'set' => ['strtolower'],
                'get' => ['trim'],
            ],
        ];
    }
    
    Custom pipes:
    $user->email = 'TEST@example.com'; // Triggers `strtolower` on set
    

Integration Tips

  • Combine Traits: Use multiple traits in a single model (e.g., Searchable + Validable for searchable, validated resources).
  • Service Layer: Abstract Eloquence logic into services to decouple from models:
    class PostService {
        public function search(string $query) {
            return Post::search($query)->get();
        }
    }
    
  • API Resources: Pair with Validable for API request validation:
    use Sofa\Eloquence\Validable\Validable;
    
    class StorePostRequest {
        use Validable;
    
        protected $rules = [
            'title' => 'required|max:255',
        ];
    }
    

Gotchas and Tips

Pitfalls

  1. Searchable Driver Mismatch:

    • Defaults to database driver (full-text search). If using MySQL, ensure FULLTEXT indexes exist:
      ALTER TABLE posts ADD FULLTEXT(title, body);
      
    • Fix: Configure searchable.driver in config/eloquence.php (e.g., scout, algolia).
  2. Metable JSON Overhead:

    • Storing meta as JSON bloats the database. For large meta data, consider:
      • A separate meta table.
      • Caching meta in Redis.
  3. Validable Mass Assignment:

    • Gotcha: $model->fill($data)->validate() bypasses mass assignment rules.
    • Fix: Use $model->validate($data) to respect $fillable.
  4. Mutable Performance:

    • Chaining mutators (e.g., set + get) can slow down bulk operations.
    • Tip: Disable mutators for bulk operations:
      $user->disableMutators();
      User::where(...)->update(...);
      $user->enableMutators();
      
  5. Mappable Ambiguity:

    • Conflicts if mapped attributes overlap with existing model methods.
    • Tip: Prefix mapped attributes (e.g., _mapped_total).

Debugging

  • Searchable Queries: Log raw queries with:
    \DB::enableQueryLog();
    Post::search('test')->get();
    \DB::getQueryLog();
    
  • Validable Errors: Dump validation errors:
    dd($model->errors()->toArray());
    
  • Metable Serialization: Check JSON encoding/decoding with:
    $meta = $model->getMeta('key');
    json_last_error(); // Debug JSON issues
    

Config Quirks

  1. Searchable Driver Options:

    • Custom drivers require implementing Sofa\Eloquence\Searchable\Contracts\SearchableDriver.
    • Example for Scout:
      'searchable' => [
          'driver' => 'scout',
          'options' => [
              'model' => 'App\Models\Post',
          ],
      ],
      
  2. Metable Storage:

    • Defaults to meta column. Override with:
      protected $metaColumn = 'custom_meta';
      
  3. Mutable Defaults:

    • Set default values for mutators:
      protected $mutable = [
          'status' => [
              'set' => ['default:draft'],
          ],
      ];
      

Extension Points

  1. Custom Searchable Drivers:

    • Extend Sofa\Eloquence\Searchable\AbstractDriver for new backends (e.g., Elasticsearch).
  2. Validable Rules:

    • Dynamically add rules:
      $user->addRule('email', 'unique:users
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui