Capabilities Vs User Meta

There is no one answer, because both have pros and cons depending on what you want to store and why.

A (probably non-exhaustive) list of differences to consider for a choice:

  • Capabilities are designed to check if a user can do something or not. user_can and current_user_can are there to help you to check user permissions. You can implement that with user meta too, but makes no sense once you have that feature in core.

  • There is no doubt that capabilities can be used to group users with similar characteristics, even if the groups are not related to permissions. In that case capabilities are for users somewhat similar to what taxonomy terms are for posts. user_can function can be used to check if a user has a capability or not (similar to has_term) but there is no core function that does the same for meta. However, retrieve a collection of users by capabilities is probably more expensive than retrieve users by a simple meta query (it’s a guess, not based on real performance profiling data).

  • To filter on the fly (without db change) all the capabilities assigned to a user is pretty easy (especially if cap are checked with user_can / current_user_can and there is no reason why not), while doing the same for meta is much harder.

  • Meta can handle nested data (e.g. arrays and even different (sets of) values for same meta key). That’s not possible with capabilities.

  • Capabilities can be grouped in roles. And roles also have a UI in the backend that allows assigning a “set” of capabilities by assigning a role. There is no such benefit for meta.

  • Capabilities are independent entities from users, and they survive users: if you delete all users that have a capability, it stays there. The same does not apply to meta: all meta goes with a user if it is deleted.

Edit

After the edit on the OP, I would say that capabilities are much better: you are implementing with meta something that core already does with capabilities, and is exactly what capabilities are intended to be.

As example, think to add_menu_page function, it has a $capability argument that lets you show a menu page only to users that have that capability.

This is only an example, there are different functions that accept capabilities as an argument.
Moreover, as said in first point before the edit, it makes no sense to implement from scratch a feature that core already has.

Leave a Comment