Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

GoldeNx3's avatar

EAV - Entity Attribute Value (Doesnt work!) or JSON?

Hello, I'm fighting with EAV (Entity Attribute Value) function second week.

I have Offers table, where people can store data, for eg:

Table offers contains id, title, desc, price. I want to store attributes for this table. User can choose for eg. Color: blue, red, green. And then he can apply offer to the server. Offe rshould looks like:

ID: 1 Title: Citroen Cars Desc: Description of selling cars Price: 10000 Attributes: Color: Blue, green, red Engine: 2.0, 1.6

Already I made 3 tables:

offers, attributes, values, attribute_offer.

offer table

https://pastebin.com/xJVPxUX3

attributes table

https://pastebin.com/qG1ULrPQ

attribute_offer table (This table is pivot, it connecting attribute with offer)

https://pastebin.com/J5jSaEhT

values table

https://pastebin.com/

Models:

Attribute Model:

https://pastebin.com/YJWQHnnz

Offer Model:

https://pastebin.com/xMGZpniU

I have no idea, how to connect OfferID with Values table. Now when i retrieve Offer I get attributes, but attribute values Im getting all, no matter if this value is assigned to offer or no. So if I get attributes, Im getting values assigned to this attribute, and I want to get values, assigned to attribute and offer. And it must be able to filtrate this data, to find all card with color red.

Or maybe is there any other way to do that? I was read about JSON, but I think its harder to implement.

0 likes
6 replies
martinbean's avatar
Level 80

@GoldeNx3 Instead of having a separate values table, add a value column on your attribute–offer pivot table:

$table->primary(['attribute_id', 'offer_id', 'value']);
$table->unsignedInteger('attribute_id');
$table->unsignedInteger('offer_id');
$table->string('value');
$table->i

You can then load attributes and their values from a relation on your Offer model:

class Offer extends Model
{
    public function attributes()
    {
        return $this->belongsToMany(Attribute::class)->withPivot('value');
    }
}
<dl>
    @foreach($offer->attributes as $attribute)
        <dt>{{ $attribute->name }}</dt>
        <dd>{{ $attribute->pivot->value }}</dd>
    @endforeach
</dl>
GoldeNx3's avatar

Okay, but now I can assign only one value to attribute (Because there is error while I'm adding another record to attribute_offer with the same attribute_id and offer_id)

I removed primary keys on attribute_id and offer_id and assign primary key on ID, then I can add more record.

While I have 2 records in attribute_offer (One is value Blue, second is Red), output look like this:

Color: Blue, Color: Red. How to do, to output word "Color" only once, to make smthg like that:

Color: Blue, Red.

martinbean's avatar

@GoldeNx3 Yeah, you’d want the primary key over all three columns. An offer should be able to have the same attribute multiple times, but each instance to have a different value.

GoldeNx3's avatar

I think it is solution for my problem. But one last question. If cars have three different colors: blue, red, green. How to make query to get all cars, that have color green and red?

martinbean's avatar

@GoldeNx3 You might want to look into something like Algolia if you want to search products based on facets like that.

1 like
GoldeNx3's avatar

@martinbean Got it! But one last question.

While I do

@foreach($offer->attributes as $attribute) {{ $attribute->name }} {{ $attribute->pivot->value }} @endforeach

This function return me all of the attributes from database. How to get control which attribute is it? Something like array where I can store all attributes for offer, and then output like that:

echo $offerAttributes['Color'];

And this will output all colors from database.

Please or to participate in this conversation.