0 votes

Hey everyone, i just wanted to say that one thing that has always been a pain is the time it takes to write out all the properties and model relationships into the code comments in order to get autocomplete in your IDE's.

I would imagine that this could be a very simple task for skipper to handle this because all of the relationships are already being defined for you.

Would it be too much to ask for the function return methods to show the proper relationships, and the abstract models to list out all the columns on the database along with their types?

/**
* @property int $id
* @property string $the_thing
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property \App\Models\Relation $relation
*/

That type of stuff would be super helpful and save us countless hours of typing :)

in Solved by (160 points)
recategorized by

Hello, thank you for the suggestion.

Unfortunately, although this can look like a very simple task, in reality, it's very hard and almost impossible to achieve.

Only to be sure, we're talking about Doctrine ORM or Laravel ORM?

Because in Doctrine, Skipper is updating only @ORM annotations and we're not able to export/modify/remove any other annotation. It's because is very hard to touch other @annotations and not break anything else. (For example, when the property is removed from ORM, this doesn't have to mean that the user wants to remove it also from the code, etc.).

On the other side, in Laravel, we're exporting complete base model file and we should be probably able to export also these properties (but only to the base class, not to derived class).

So, now it depends about which ORM framework we're talking ;-).

Thanks for the quick follow up Ludek,

In this case, I'm referring to Laravel's ORM and the abstract models which are directly generated from skipper. I see these models get completely overwritten every time you do an export, so it would be VERY beneficial to do that for anyone using the Laravel Eloquent ORM...

Great, Laravel is the better option ;-).

In this case, would you be able to send me an example project where we can see any possible combination you want to generate?

We're not native Laravel devs so would be great to have any sample which we can use. Also would be great if we can cooperate on testing after we implement it.

If you agree, please contact me directly at [email protected].

Thanks

Hello Ryan, I'm not sure you're receiving my emails. Unfortunately, I didn't receive original attachments with the examples.

Hello Ryan, please contact me in case you're still interested in this function. Thanks

Hey Ludek,

Sorry for not responding - yes I've gotten the emails but have been blinded by day job activity and haven't really spent much time with this since. I think the easiest thing to communicate here ( without any need for a schema ) would simply be to look at what a typical code hint would be for a model, or a typecast...

/**
  * @property int $id
  * @property string $the_thing
  * @property \Carbon\Carbon $created_at
  * @property \Carbon\Carbon $updated_at
  * @property \App\Models\Relation $relation
  * @property \Illuminate\Database\Eloquent\Collection $items
*/

Where I'm showing the App\Models\Relation that's the part where you're defining the "hasMany" or "belongsTo" etc. in your skipper app. Seems very easy to do considering you're already creating the relationship functions with the models. Why not add the hinting for the relation, or the "eloquent collection" that's being modeled? All this really does is save the typing for people like myself who really prefer to see get proper hinting and colors across your IDE just for ease of use really.

Hello Ryan, I understand what you would like to achieve, but we would need some codebase for testing.

Unfortunately, one fragment isn't enough. We're not active Laravel developers so we would appreciate it if you can share you complete code together with documentation links where we can find all possible options.

Becasue of that I tried to contact you directly via email because to be able to work on this feature we would need slightly more cooperation from you.

So as I wrote before, would you be able to send us a complete example project which we can use for the development?

Thanks a lot
Ludek

Hey Ludek,

You can very easily understand this with a single abstract model file. You're already stubbing out the functions for the relationships or the "casts" for the model properties... all I'm saying is that you would want to add in another "model property" or "relation" in the class declaration.

<?php

 namespace App\Models\AbstractModels;

 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\SoftDeletes;

 /**
 * Class AbstractCustomer
 * @package App\Models
 *
 * @property int $id
 * @property int $team_id
 * @property string $email
 * @property string $first_name
 * @property string $last_name
 * @property string $cell_phone
 * @property string $profile_photo_path
 * @property \Carbon\Carbon $subscribed_to_email_at
 * @property \Carbon\Carbon $unsubscribed_to_email_at
 * @property \Carbon\Carbon $subscribed_to_mail_at
 * @property \Carbon\Carbon $unsubscribed_to_mail_at
 * @property \Carbon\Carbon $subscribed_to_sms_at
 * @property \Carbon\Carbon $unsubscribed_to_sms_at
 * @property \Carbon\Carbon $subscribed_to_phone_at
 * @property \Carbon\Carbon $unsubscribed_to_phone_at
 * @property \Carbon\Carbon $created_at
 * @property \Carbon\Carbon $updated_at
 * @property \Carbon\Carbon $deleted_at
 * @property \App\Models\Team $team
 * @property \App\Models\Company|null $company
 * @property \Illuminate\Database\Eloquent\Collection $orders
 * @property \Illuminate\Database\Eloquent\Collection $orderDetails
 * @property \Illuminate\Database\Eloquent\Collection $addresses
 * @property \Illuminate\Database\Eloquent\Collection $notes
 * @property \Illuminate\Database\Eloquent\Collection $phoneNumbers
 * @property \Illuminate\Database\Eloquent\Collection $companies
 */
abstract class AbstractCustomer extends Model
{
    use SoftDeletes;

    /**
     * Primary key type.
     *
     * @var string
     */
    protected $keyType = 'string';

    /**
     * Primary key is non-autoincrementing.
     *
     * @var bool
     */
    public $incrementing = false;

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'id' => 'string',
        'team_id' => 'string',
        'email' => 'string',
        'first_name' => 'string',
        'last_name' => 'string',
        'cell_phone' => 'string',
        'subscribed_to_email_at' => 'datetime',
        'subscribed_to_sms_at' => 'datetime',
        'subscribed_to_mail_at' => 'datetime',
        'subscribed_to_phone_at' => 'datetime',
        'unsubscribed_to_email_at' => 'datetime',
        'unsubscribed_to_sms_at' => 'datetime',
        'unsubscribed_to_mail_at' => 'datetime',
        'unsubscribed_to_phone_at' => 'datetime',
        'profile_photo_path' => 'string',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'deleted_at' => 'datetime'
    ];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'team_id',
        'email',
        'first_name',
        'last_name',
        'cell_phone',
        'profile_photo_path'
    ];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['deleted_at'];

    public function team()
    {
        return $this->belongsTo('\App\Models\Team', 'team_id', 'id');
    }

    public function orders()
    {
        return $this->hasMany('\App\Models\Order', 'customer_id', 'id');
    }

    public function orderDetails()
    {
        return $this->hasMany('\App\Models\OrderDetail', 'customer_id', 'id');
    }

    public function addresses()
    {
        return $this->morphMany('\App\Models\Address', 'Addressable', 'addressable_type', 'addressable_id');
    }

    public function notes()
    {
        return $this->morphMany('\App\Models\Note', 'Noteable', 'noteable_type', 'noteable_id');
    }

    public function phoneNumbers()
    {
        return $this->morphMany('\App\Models\PhoneNumber', 'PhoneNumberable', 'phone_numberable_type', 'phone_numberable_id');
    }

    public function companies()
    {
        return $this->belongsToMany('\App\Models\Company', 'customer_has_company', 'customer_id', 'company_id')->withPivot('primary', 'title', 'division', 'phone', 'extension', 'notes', 'email');
    }
}

great, thanks!

It's clear now. We will try to implement it in next days and let you know with testing.

Hey thanks... I don't know if I mentioned this previously - but the main reason for this feature is that your models are all considered "untouchable" because they get overwritten. Typically I would want to add these mappings on the abstract file to keep smaller extended models / less to scroll through in the parent model but still get type-hinting.

I think I've defined "lazy" by asking for this, but the reality is it's a very reasonable benefit for a tool like this to provide. Why not right? :)

Thanks again for your help!

I don't think this is "lazy", it's time-saver and this is the reason why skipper is created ;-)

1 Answer

0 votes

New beta version with this feature is available here:

https://www.skipper18.com/support/402/downloads-skipper-beta

Please test it on your model and let me know.

by Skipper developer (141k points)