deiucanta / laravel-smart

Automatic Migrations, Validation and More
48 stars 7 forks source link

Idea: lookup models #1

Closed ajthinking closed 6 years ago

ajthinking commented 6 years ago

First, this package gonna rock big time! Hope Taylor addresses it.

Small idea, possibly offscope but anyways: When you register the state of the migrations, could it also register the models itselfs somehow? So we can do something like: app()->models() and get a listing of all the models?

Cheers!

deiucanta commented 6 years ago

Hey @ajthinking :) thanks for the feedback!

Your suggestion is interesting :) how would it help you?

ajthinking commented 6 years ago

I remember wanting to extraxt all model data to ui tables on the fly. But laravel is not aware of the models so had to resort to scanning the directory tree. It just came to mind because your package idea collects many loose ends in laravel and this feels like a loose end. The framework should have the models registered or at least listable.

It would also be good for github.com/furey/tinx

Again, cant wait for this package, let me know if you want any help/feedback!

russsiq commented 6 years ago

I don't know, but it works. Model is created dynamically, and there is access to its attributes

<?php

namespace BBCMS\Http\Controllers\Common;

use BBCMS\Http\Controllers\BaseController;
use BBCMS\Http\Requests\Common\ToggleRequest;

class ToggleController extends BaseController
{
    /**
     * Namespace to located models.
     *
     * @var string
     */
    protected $modelsNamespace = '\BBCMS\Models';

    public function attribute(ToggleRequest $reqest)
    {
        try {
            // Prepare local variables.
            $id = $reqest->id;
            $class = $this->modelsNamespace . '\\' . $reqest->model;
            $model = app($class);
            $attribute = $reqest->attribute;

            // Only castables attribute of boolean type may be toggled.
            if (! $model->hasCast($attribute, ['bool', 'boolean'])) {
                throw new \LogicException(sprintf(
                    'Attribute `%s` not defined in $casts of [%s] as boolean type.', $attribute, $class
                ));
            }

            // Find $item in this $model. Select all attribute to authorize.
            $item = $model->whereId($id)->firstOrFail();

            // Check permission to update $model $item.
            $this->authorize('update', $item);

            // Update attribute, if exists.
            $item->update([$attribute => ! $item->{$attribute}]);

            return redirect()->back()->withStatus(__('msg.complete'));
        } catch (\Exception $e) {
            return redirect()->back()->withErrors($e->getMessage());
        }
    }
}
russsiq commented 6 years ago

You're not going to check all the models for compliance, and the presence of attributes on each boot of the application. This can be done by directly accessing the model.

ajthinking commented 6 years ago

Nice one @russsiq, though it assumes you know the namespace and has an model instance to work with?

russsiq commented 6 years ago

You're right.

russsiq commented 6 years ago

Perhaps this information will help:

Illuminate\Database\Schema\Blueprint used \Illuminate\Support\Traits\Macroable

deiucanta commented 6 years ago

For now, I have a config file (config/smart.php) where the developer is supposed to manually add all the models. We could add them automatically upon creation php artisan smart:model or we could scan the entire namespace for models.

I need the list of models in order to generate the diff which is used to generate the migration.

robsontenorio commented 6 years ago

Maybe using reflection we can get all models that extends from Smart\Model... ? If feasible, we can eliminate config/smart.php

deiucanta commented 6 years ago

I'm not sure if reflection can scan through the file system.

We can scan the app directory and look for classes that implement the Model. However, I'm concerned about performance. If the user has all the models in the root of app then, it should be fine. On the other hand, if the user has a nested directory structure and the models are spread across multiple folders... Anyway, this the result should be cached and then the scanning performance doesn't matter that much.

So far, we have two options for this

  1. Scanning the file system & caching the result.
  2. Adding the model automatically upon creation (php artisan smart:model)
robsontenorio commented 6 years ago

I think performance is a minor issue because this lookup operation is cheap.

Sync manually files is boring :(

deiucanta commented 6 years ago

For now I will implement the second option. Whenever a model is generated it will be added to the list automatically.

robsontenorio commented 6 years ago

Agree. It is a good start.

deiucanta commented 6 years ago

@robsontenorio I just merged a PR for this.

It's a rudimentary file generation. Not the most flexible approach but it works.