Skip to content

feat: ✨ [NEW FEATURE]Create relation between Item and Event, Item and Place, Place and Event #499

Open
create-issue-branch[bot] wants to merge 7 commits into
master/devfrom
feature/issue-498-_NEW_FEATURE_Create_relation_between_Item_and_Event_Item_and_Place_Place_and_Event
Open

feat: ✨ [NEW FEATURE]Create relation between Item and Event, Item and Place, Place and Event #499
create-issue-branch[bot] wants to merge 7 commits into
master/devfrom
feature/issue-498-_NEW_FEATURE_Create_relation_between_Item_and_Event_Item_and_Place_Place_and_Event

Conversation

@create-issue-branch
Copy link
Copy Markdown
Contributor

Original issue description

Description of the desired solution
• Instead of manually adding which event a person was in, a relation must be created between the person and the event. Avoids having an item in multiple events.
• An item can have a localization, so a relation between place and item is necessary
• A event can have a localization, so a relation between place and event is necessary
closes #496

closes #498

@create-issue-branch create-issue-branch Bot added the New feature New feature or request label Jul 16, 2024
@create-issue-branch create-issue-branch Bot changed the title [NEW FEATURE]Create relation between Item and Event, Item and Place, Place and Event feat: ✨ [NEW FEATURE]Create relation between Item and Event, Item and Place, Place and Event Jul 16, 2024
@create-issue-branch create-issue-branch Bot changed the title [NEW FEATURE]Create relation between Item and Event, Item and Place, Place and Event feat: ✨ [NEW FEATURE]Create relation between Item and Event, Item and Place, Place and Event Jul 16, 2024
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Aug 7, 2024

@rebeccadjim rebeccadjim requested a review from lduf August 8, 2024 19:05
@rebeccadjim rebeccadjim marked this pull request as ready for review August 8, 2024 19:05
…relation_between_Item_and_Event_Item_and_Place_Place_and_Event
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Oct 8, 2024

@lduf lduf self-assigned this Oct 8, 2024
Copy link
Copy Markdown
Contributor

@lduf lduf left a comment

Choose a reason for hiding this comment

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

This should work, but I would prefer to use something more dynamic. There are many code similarities / repetition and adding a new type of relation won't be easy.
I explained what I was thinking to do to chatGPT and ask it to explain it in a more comprehensive way.

Here is what it said :

Explanation and Detailed Proposal

Objective:

The goal is to create a flexible and scalable system to manage relations between different models (e.g., Item, Place, Event) in a way that avoids code duplication and adheres to clean code principles.

Current Issues:

The current approach in the PR involves a lot of repetitive code to establish relationships between models. This can be improved using a more abstract and generalized approach.

Proposal:

  1. Abstract Class/Interface:

    • Create an abstract class or interface that defines the common behavior for all models that can have relations. This class will be called Relationable.
  2. Inheritance:

    • Each model that needs to have relations (e.g., Item, Place, Event) will inherit from the Relationable class.
  3. Allowed Relations:

    • Define a list of allowed relations in the parent class. This list will specify which models can be related to each other.
  4. Dynamic Relation Methods:

    • Use dynamic methods to handle the creation and management of these relations, reducing the need for repetitive code.

Example Implementation:

1. Creating the Relationable Abstract Class:
abstract class Relationable extends Model
{
    protected static $allowedRelations = [];

    public function addRelation($relationType, $relatedModel)
    {
        if (!in_array(get_class($relatedModel), static::$allowedRelations)) {
            throw new Exception("Relation not allowed");
        }

        // Logic to add the relation
        // This is a simplified example, and you would expand on it as needed for your project.
        return Link::create([
            'from_id' => $this->id,
            'from_type' => get_class($this),
            'to_id' => $relatedModel->id,
            'to_type' => get_class($relatedModel),
            'relation_type' => $relationType,
        ]);
    }

    public function getRelations($relationType)
    {
        // Logic to get the relations
    }
}
2. Extending Models from Relationable:
class Item extends Relationable
{
    protected static $allowedRelations = [Place::class, Event::class, Item::class];
}

class Place extends Relationable
{
    protected static $allowedRelations = [Event::class];
}

class Event extends Relationable
{
    protected static $allowedRelations = [Event::class];
}
3. Using the New Structure:
$item = Item::find(1);
$place = Place::find(2);
$event = Event::find(3);

$item->addRelation('location', $place); // Allowed
$item->addRelation('participation', $event); // Allowed

$place->addRelation('host', $event); // Allowed

$event->addRelation('related', $event); // Allowed

$place->addRelation('residence', $item); // Throws exception (not allowed)

Detailed Example:

  1. Defining a Relation:

    • In the Item model, we can define that it can have relations with other Items, Places, and Events.
    • In the Place model, we define that it can have relations with Events only.
    • In the Event model, we define that it can have relations with other Events.
  2. Handling Relations:

    • The addRelation method in the Relationable class checks if the relation is allowed before creating it.
    • This ensures that you cannot create invalid relations, maintaining the integrity of your data.

Benefits:

  • Reduced Code Duplication: By centralizing the relation logic in the Relationable class, you avoid repetitive code across different models.
  • Flexibility: You can easily add or remove allowed relations by modifying the $allowedRelations array in each model.
  • Scalability: This approach is scalable and can easily accommodate new models and relations in the future.

This structure ensures a clean, maintainable, and scalable way to manage relations between different models in your project.


PS : you might need to refactor many models and migration.
I think you should add from_type and to_type columns to support polymorphic relationships to links table. This allows any model to be related to any other model.

Comment thread src/app/Models/Place.php
return $this->hasOne(ApiLog::class, 'id', 'apiLog_id');
}

public static function getAllPlacesNames() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use pluck instead :

public static function getAllPlacesNames() {
    return self::pluck('name', 'id');
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't re specify 'edit' and all that stuff, use the one from src/resources/lang/en/common.php

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't re specify 'edit' and all that stuff, use the one from src/resources/lang/en/common.php

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't re specify 'edit' and all that stuff, use the one from src/resources/lang/en/common.php

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't re specify 'edit' and all that stuff, use the one from src/resources/lang/en/common.php

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't re specify 'edit' and all that stuff, use the one from src/resources/lang/en/common.php

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't re specify 'edit' and all that stuff, use the one from src/resources/lang/en/common.php

Copy link
Copy Markdown
Contributor

@lduf lduf left a comment

Choose a reason for hiding this comment

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

Add tests to make sure everything is working 😉

@vqlion vqlion self-assigned this Oct 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[NEW FEATURE]Create relation between Item and Event, Item and Place, Place and Event

3 participants