Jump to content

Managing user provided settings


 Share

Recommended Posts

I've been using below database schema to manage account settings for multitenancy applications (the same approach could be used for user settings).  Each Account would have a Setting entity with a value for each record in the setting table and that value would either be the default setting.default_value or the overridden value in account_setting (which is the only table which the user can modify), and account_setting would either use the setting_allowed_value_id or the unconstrained_value.

It worked pretty well and my biggest issue was needing to remember whether some giving setting value was stored in the account entity or these tables, and to a lesser degree needing to execute multiple queries to retrieve the data.

While I don't exactly know why, I now question this approach as it might be some anti-pattern and lead to future unforeseen issues, and would like other's advise.

First of all, should I totally abandon this approach and just store the values directly in the entity?

If not, any suggestions how to make it smell more like a normal entity?  I could make the Setter entity have getter and setter methods for each property but then I will need to remember to keep the class and setting table synchronized.  Don't really know what I am asking here...  EDIT.  Maybe I should have asked how should it be incorporated into a project using Doctrine.

Lastly, not expecting an answer as I know there isn't too much Symfony use here but anyone know of some bundle which will take care of this type of scope?

Thanks

settings-erd.PNG.a1f3108ce723e5f3c465235aac571b1e.PNG

Edited by NotionCommotion
Link to comment
Share on other sites

The structure seems fine to me.

For the doctrine/symfony integration I see two possible approaches.

  1. Create a view that you can query against to get the configured value for a setting (either the value in account_setting or the default value) and then make a read-only entity based on that view.  Changing a setting would require creating/updating an entity for the underlying account settings table rather than the read-only entity.
  2. Create a service that you can use to query for a setting.  The service would check for a account setting first, then fall back.  You could have the service load all the relevant data on the first inquiry rather than run separate queries on each inquiry.  The service could also include the code needed to create/update account settings.

I'd probably go with option #2.  It keeps the code for settings more centralized and consistent.

 

Link to comment
Share on other sites

Thanks kicken,

Regarding option 1, you mean a SQL view or something else?  If so, I too will lean towards option 2 as awesome SQL is great until I forgot what I did and this being a one-off will likely forget sooner than later.

Regarding option 2, there is nothing magical about a service when using symfony, right? Just a class with some normal PHP which gets injected and has the applicable methods.  I think this is the case but am still a bit perplexed by some symfony approaches.

Also, a new wrinkle.  I don't have just a single thing which needs setting values but a second. And maybe later a third or more...  Which seems the whole point of reusable code.  The really old me would have used a bunch of inheritance.  The kind of old me would have injected the entity which the settings are being saved for into your recommended service option but then probably used some instanceof's to perform some logic.  Actually, scratch that, would have used an interface to enforce some method.  Need to figure out what the new me wants to do...

Link to comment
Share on other sites

Option 1, yes just a SQL view.  You could create a query that will left join the account_settings table and generate a result set that contains each setting and the value from the account_settings table if set, or the default value from the setting if not.  You could then map that view to a read-only entity and add it as a relation to your account entity.

 

Option 2, yes a service i just some class that you use to perform some task which is accessible via the container/dependency injection.   Most things are "just normal php code", they just get categorized based their purpose.  In general Services are code that generally implement your business logic;  Controllers handle the your HTTP requests, generating responses and collecting input data;  Entities/Data objects are simple data structures for moving data around the system in an organized way (vs just array's everywhere for example).

 

Not really sure what you mean by the new wrinkle, so no advice there I guess.

Link to comment
Share on other sites

16 hours ago, kicken said:

Option 2, yes a service i just some class that you use to perform some task which is accessible via the container/dependency injection.   Most things are "just normal php code", they just get categorized based their purpose.  In general Services are code that generally implement your business logic;  Controllers handle the your HTTP requests, generating responses and collecting input data;  Entities/Data objects are simple data structures for moving data around the system in an organized way (vs just array's everywhere for example).

I like that.  Maybe it is out there but I haven't seen anything so to the point but just a bunch of cats and dogs extending animals.  Would have been REAL helpful a few years back.  Still helpful now as it reminds me that things are not so mysterious.

 

16 hours ago, kicken said:

Not really sure what you mean by the new wrinkle, so no advice there I guess.

If I am only managing properties for a single thing, I envision a class which might only have a single method.

PropertyService::getProperties(User $user):PropertyObject

But now it is an app for managing clubs.  Each account-club will have properties such as name, subject, address, and each club has many user-members (many-to-one and not many-to-many) who have properties such as name, birthday, email, etc.

I could make both Account and User implement an interface and use PropertyService::getProperties(ThingThatHasProperties $thing):PropertyObject, but am concerned that it will get too complicated.  I could inject $thingThatHasProperties into PropertyService's constructor but then PropertyService is no longer stateless.  I could inject $thingThatHasProperties class name ("User", "Account") into PropertyService's constructor and then later call PropertyService::getProperties(User $user) but it seems redundant.  I know there are likely a million ways to do this and maybe they are all the same...

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.