I
I
Ilya Myasin2015-12-11 03:06:37
CMS
Ilya Myasin, 2015-12-11 03:06:37

How to store context dependent values?

Hey! Here and there I come across a problem when it is necessary to save (in a relational database) the state of an entity that depends on some context.
I put the "Drupal" tag, because in Drupal there is definitely something like that)) Drupal people, tell me!
I will give an example for clarity.
There is a form field for entering news text. We want to set up a tooltip description and a set of wysiwyg editor buttons for it, for example. The site has two news feeds, and when adding to each of them, you need to show your own tooltip. And the set of buttons may depend on the group in which the current user is a member. In total, when displaying the field, we need to get the context (user group and news feed number) and collect the values ​​​​corresponding to this context.
The first candidate is this design:

field_id | parent_id | user_group   | newsfeed_id | label  | description          | buttons 
--------------------------------------------------------------------------------------------
1        | null      | null         | null        | 'Текст' | 'Текст новости'     | 'basic'
2        | 1         | 'admin'      | null        | null    | null                | 'full'
3        | 1         | null         | 2           | null    | 'Текст пресс-релиза'| null
4        | 3         | 'sekretarsha'| null        | null    | null                | 'none'

We store everything in one table, the context is set by the values ​​of the group_id and newsfeed_id columns. NULL-filled properties are taken from the string referenced by parent_id. What I don't like here:
1. if it turns out that something else affects the context, you will have to add a column (change the schema).
2. magical division of strings into "real" and "redefining".
3. the context can only be set by equality (if you need something like "registration > 3 months" - again we go to conjure with the scheme).
I develop the idea further. Okay, since we don't know exactly how the context works, let's do something like Entity-Attribute-Value for it:
field:
field_id | context_id | label  | description | buttons

context:
context_id | parent_context_id

context_definition:
context_id | property | operator | value

Now not fields are inherited, but contexts (hmm, is that good?). The context is determined by a set of attributes, and for the attribute we can set not only the equality condition, but also something more tricky. For example, to identify secretaries who have been registered for more than 3 months:
context_id | property   | operator  | value
--------------------------------------------------
1          | 'reg_age'  | >         | 7776000
1          | 'group'    | =         | 'sekretarsha'

It is clear that you can make a list of all attributes and store id instead of attribute code.
You can not stop there, but leave in the field table only what exactly cannot be overridden, and store all other values ​​in EAV with a filter by context - get rid of the "magic" (fake) rows in the main table, well, in general, we can use this construction for all such cases (so as not to touch the circuit ever). Oh shit, something like this:
value_definition:
entity_type | entity_id | context_id | property | value

But damn... it all smells strongly of a bicycle :)
I want to ask the respected community: is there any pattern for this class of tasks, or a product where it is implemented in a reusable form? Or at least google for some words :)
Similar tasks:
- customize the appearance of the block on the site depending on the current section / user / referral source / running A/B test, etc.
- set the rights to operate on the object depending on the user groups / object properties / the object belongs to the user / moon phases, etc.
- set a discount for the product depending on...
There is not enough data, you can pull everything out with two queries and scatter it as it should be already in memory.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vitaly F., 2015-12-11
@FuN_ViT

If it’s about the news text input block, then the easiest way is to add a TypeId to the model, and then store the NewsTypes table with the settings in the database in the form of serialized data (yes, at least json).
In general, trying to store business logic using structural features / database fields is still fun. I have experience. This leads to slowdowns and difficulties in checking / testing ...
Perhaps at the initial stage it will be easier to describe the business logic in code (a separate class) than to rush into the embrasure.

N
nozzy, 2015-12-11
@nozzy

Are you considering NoSQL?
You can use Postgre and store everything in JSONB.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question