I have a module that should render a menu depending on the user roles.
We used to use cancancan
gem but since we got a new specification it's being deprecated.
I have an association that goes like this. A many_to_many relationship with User
and Role
, another many_to_many relationship with Role
and Menu
, so a User
has a nested many_to_many relationship with Menu
.
What I'm trying to do is render a menu depending on the user role. so I have this helper module:
module MenuHelper
# ! MENU MAPPING ===============================
MENU_NAMES = {
orders: '<%= main_menu_tree Spree.t(:orders), icon: "shopping-cart", sub_menu: "orders", url: "#sidebar-orders" %>',
workflows: '<%= tab *Spree::BackendConfiguration::WORKFLOW_TABS, label: Spree.t(:workflows), icon: "flash" %>',
}
# ! MENU MAPPING ===============================
# this will return menu names
# @params {ARRAY} menu_names are the allowed menu that the user can access by its role
# @returns {ARRAY}
def user_menus(menu_names = [])
samp_arr = []
menu_names.each do |m_n|
samp_arr << MENU_NAMES[:"#{m_n.downcase}"]
end
samp_arr
end
end
and on my shared/_menu.html.erb
I have this.
<% spree_current_user.menus.pluck(:name).each do |n|%>
<ul>
<%= n%>
</ul>
<% end %>
on the view though it will turn into a string. I expected this behavior but is there a way to evaluate this as a method? since main_menu_tree
and tab
is just a method or maybe there is a better way to solve this?
As you have menu_names
you can create a new template (we name it as partial) for each menu, see the example:
app/
views/
menus/
_menu_name_1.html.erb
_menu_name_2.html.erb
If you create these partials, you should be able to do something like:
<% spree_current_user.menus.pluck(:name).each do |menu_name| %>
<ul>
<%= render "menus/#{menu_name}" %>
</ul>
<% end %>
It will concatenate the name of menu with the path of the file to render and all should work fine!