This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.

kubuss8822438
kubuss8822438

Hi, I have relation like this:

Category hasMany Products

Category hasMany Features

and also

Product belongsToMany Features (m2m relation)

I would like to display in backend page of Product-Features relation (as checkboxes). But I would like to display only the Features that belongs to the same Category as a Product. I know how to do this in Laravel, f.ex:

$limitedFeatures = array();
foreach($product->features as $feature) {
    if ($feature->category_id == $product->id)
        $limitedFeatures[] = $value;
}

But don't know where to put this logic in the backend of October.

Last updated

Felix@DevINX
Felix@DevINX

Hello @kubuss8822438!

You should use the Has Many Through relationship, but you will need to change your database a bit. You will need to remove the Product belongsToMany Features.

So this is how it will work. The Product model will look to the Feature model but through the Category model. To make this change, take a look at database/relation#has-many-through docs.

After on the backend use the forms widget relation.

I am not sure this is exactly how you want to do it, but take a look at the relation section of the docs to learn more about what October can do. Then choose the appropriate relationship.

Hope it helps you!

kubuss8822438
kubuss8822438

Hi, thanks for your answer.

However thats not exactly what I need. Let's take an example. We have 2 categories: Car and Bike.

Car (category) has Features: Strong engine, 5 seats and Large trunk

Bike (category) has Features: Comfort seat, Dynamo light and Disc brakes

Now

Bmw Z4 (product that is Car) has Strong engine

Bmw 1 (product that is Car) has Strong engine, 5 seats, Large trunk

Giant Bike (product that is Bike) has Comfort seat and Disc brakes

And when adding new Bike I want to display all possible features (for that category) as a checkboxes. So has many through does not seems to be a way to achieve that functionality.

Felix@DevINX
Felix@DevINX

This is something quite complicated, but not impossible!

OctoberCMS does not support "out of the box" this situation, but you can build it. You will need the following :

  • A custom form widget to display the checkbocks in the backend.
  • A query scope to find the objects to be displayed. You can do somehting else, but a query scope is nice if you want more than a backend connection, a frontend connection for example.

Also, take a look at the user interface guide to make your widget. This video show how to make a custom form widget.

kubuss8822438
kubuss8822438

Okay, form widget - get it. But how to approach the scope?

I tried this for Product model:

public function scopeFeaturesForCategory($query)
    {
        return $query->where('category_id', $this->category->id);
    }

And it fails because at scope level we don't know relationship yet (app don't know witch product are we dealing with). If I hardcode id it works but this is not solution I'm looking for. Maybe I can modify it somewhere in a update/create controller.

Felix@DevINX
Felix@DevINX

As you are inside your controller for your product, I guess you product only have one category (belongsTo instead of belongsToMany). With this, you can get the ID of your category. I am not sure how to do it (nerver did it) but if you can get the value of a field on the current page, you should be able to do it. Imagine that the category id is in the $category_id var.

After, use the scope as following:

$features = Feature::featuresForCategory($category_id)->get();

// And in your model file
public function scopeFeaturesForCategory($query, $category_id)
{
     return $query->where('category_id', $category_id);
}

Please note, I have change the scope to be dynamic, not static.

kubuss8822438
kubuss8822438

Thank you very much for your advices. I found solution that works like a charm.

In Feature model I've defined a scope:

class Feature extends Model
{
    public function scopeCurrentCategory($query, $product)
    {
       return $query->where('category_id', $product->category_id);
    }
}

And Product model I've defined relation with a scope:

public $belongsToMany = [
    'features' => [
        'Path\To\Models\Feature',
        'table' => 'feature_product_pivot',
        'scope' => 'currentCategory',
    ],
];

Felix@DevINX said: Please note, I have change the scope to be dynamic, not static.

That was a key to solve this ;) Thanks again.

Last updated

1-7 of 7

You cannot edit posts or make replies: the forum has moved to talk.octobercms.com.