Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HasStatuses trait and supporting code #26

Merged
merged 5 commits into from
Mar 10, 2021

Conversation

pdbreen
Copy link
Contributor

@pdbreen pdbreen commented Mar 10, 2021

No description provided.

$table->string('name')->unique();
$table->string('applies_to')->default('order'); // Values include 'order', 'slot', 'game', 'invoice', 'payment'
$table->string('name');
$table->string('type'); // Typically, full class name for model using status
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note change to 'type' here. The HasStatuses trait defaults to using the fully qualified model name as the type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chx2 Take a look at the changes in this PR for what you're doing in tipoff/bookings with Status:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pdbreen You prefer using type instead of applies_to for this field?

CC: @sl0wik

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do. Its somewhat tied to potentially allowing a single model to have multiple, different types of statuses. But, even if that's not allowed, I think type is still a more appropriate term for this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. Thanks for the explanation

$table->text('note')->nullable();
$table->timestamps();

$table->unique(['name', 'type']);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uniqueness is not name alone - but name for a given type. Its certainly reasonable for two unrelated status types to have overlapping names.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Thanks

protected bool $dynamicStatusCreation = false;

// Assumes models can only have a single type of status
public function statusType(): string
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to decide whether or not its necessary to support a single model having multiple statuses. If yes, then a type field will be needed in the statusables record. The status(...) method would also need to allow for fetching status by arbitrary type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to have a single model supporting multiple statuses so that I have timestamps recorded of when the model was switched from one Status to another. That history will be important for keeping records.

Therefore, the current Status of a single model will be the most recent one attached to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was asking if a single model can have multiple, distinct types of status. A hypothetical example, order model has both "payment status", "shipment status" (this is same as allowing for one model to have multiple addresses).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't even consider that. Yes, that would be a great use case! Let's allow for it. Thank you!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok - type field added to Statusable model and trait methods updated to allow for status by type. If no type is supplied, full class name of model is used as type designation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

return get_class($this);
}

public function status(?string $name = null): ?Status
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the trait needs to contain a statusable() method to define the morphOne relation, this is the key interface method which returns the Status model essentially hiding the Statusable model from external use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could rename the Statusable model to AssignedStatus or StatusChange or StatusRecord or something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of those, I think AssignedStatus is most appropriate because it represents the current, point in time status. The other names imply history tracking which would require an additional table to track transitions over time (which it sounds like you want, should create an issue to add it).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why I originally created the Statusables table and why it doesn't have a unique combination requirement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather see change history tracked in another table. Using most recent timestamp as determination for current status makes me nervous (direct DB change for example). Your call. If history is retained in this table, the HasStatuses trait needs some changes to support it properly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing. For name, I'd lean towards StatusRecord - can be read as both current record & historical record. The others imply only current or only history.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect. Let's go with that. Thank you

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#27

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Name change to StatusRecord and retention of past records is now in place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

{
// When true, new statuses will be added automatically on first use
// When false, exception occurs if unknown status value is used
protected bool $dynamicStatusCreation = false;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be pulled if you only want to allow pre-defined statuses to be used. Included only because it was easy to add.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's interesting. Not sure if it is necessary since Nova allows a create resource option from within another model.

'name',
];

public static function publishStatuses(string $type, array $names): Collection
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method would be used in migrations to establish valid statuses for a given type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that. Thanks

Comment on lines +43 to +48
// Check if desired status already set
if ($currentStatus = $this->getStatus($type)) {
if ($currentStatus->id === $status->id) {
return $currentStatus;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drewroberts - want to call this out. If the requested status is the same as the current status, a new record is NOT created. If you always want a record, even if the requested status matches current status, it can be removed and tests updated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a correct implementation for what I want. Thank you!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joshtorres Could you make sure this logic is also added to GmbDetails and GmbHours in the the tipoff/location (TIPOFF/locations#44) package and PlaceDetails and PlaceHours in the tipoff/seo package (TIPOFF/seo#22)?

Copy link
Member

@drewroberts drewroberts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! 🃏

@drewroberts drewroberts merged commit 53e4a51 into main Mar 10, 2021
@drewroberts drewroberts deleted the pbdreen/feature/has-statuses branch March 10, 2021 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants