Home > Mobile >  Pass the devise user path in a partial
Pass the devise user path in a partial

Time:05-24

I'm trying to create a sidebar menu with the below information:

# app/controllers/users_controller.rb

def show
  @user = User.friendly.find(params[:id])
end
# config/routes.rb

get "/user/:id", to: "users#show"

I have the link from the dropdown menu to the current_user path:

<!-- app/views/layouts/_dropdown_menu.html.erb -->

<%= link_to "My Account", current_user %>

This is how I create the sidebar menu:

<!-- app/views/layouts/dashboard.html.erb -->

<%= render "shared/sidebar_panel" %>
<!-- app/views/shared/_sidebar_panel.html.erb -->

<%= render "shared/nav" %>
<!--  app/views/shared/_nav.html.erb -->

<% SidebarMenu.all.each do |entry| %>
  <% if entry[:group_title].present? %>
    <li ><%= entry[:group_title]%></li>
  <% end %>

  <%= render partial: 'shared/nav_submenu',
    collection: entry[:children],
    as: :sub_menu,
    locals: {parents: []} %>
<% end %>
<!-- app/views/shared/_nav_submenu.html.erb -->

<li>
  <a href="<%= sub_menu[:href] %>">
    <span><%= sub_menu[:title] %></span>
    <% if sub_menu[:subtitle].present? %>
      <span >
        <%= sub_menu[:subtitle] %>
      </span>
    <% end %>
  </a>

  <% if sub_menu[:children].present? %>
    <ul>
      <%= render partial: 'shared/nav_submenu',
        collection: sub_menu[:children], 
        as: :sub_menu, 
        locals: {parents: parents   [sub_menu]} %>
    </ul>
  <% end %>
</li>

I have a SidebarMenu model and I've added current_user path:

# app/models/sidebar_menu.rb

class SidebarMenu
  class << self
    include Rails.application.routes.url_helpers
  end

  def self.all
    [
      {   
        group_title: "Account & Contact",
        children: [
          {
            href: "#",
            title: "Account",
            icon: "...",
            children: [
              {
                href: current_user,
                title: "My Account"
              }
            ]
          },
          # ...
        ]
      }
    ]
  end
end

But it raises an error message:

undefined local variable or method `current_user' for SidebarMenu:Class

Can anyone advise me how I can fix this?

CodePudding user response:

This is how current_user method is set up by Devise: current_user is a controller method included by devise and loaded in ActionController::Base class. It is also available in the views because it is a helper method which gets included in ActionView::Base. current_user is not a url helper and it returns a User model instance which link_to can turn into a url automatically.

current_user is outside of the scope of SidebarMenu class. To fix it, just pass it as an argument:

class SidebarMenu
  def self.all user
    [{ href: user, title: "My Account" }]
  end
end

# in the view or controller
SidebarMenu.all(current_user) # => [{ href: #<User:0x0000563cc7c69198>, title: "My Account" }]

I think, a better approach is to use menu class as an object. It is more flexible and easier to use:

class Menu
  include Rails.application.routes.url_helpers

  def initialize(user:)
    @user = user
  end

  def user_menu
    {
      group_title: "Account",
      # NOTE: use url helper to return a path instead of a `User` model
      children: [{ href: user_path(user), title: "My Account" }]
    }
  end
  
  def sidebar_menu
    {
      group_title: "Main",
      children: [{ href: root_path, title: "Home" }]
    }
  end

  def all
    [sidebar_menu, user_menu]
  end

  private

    attr_reader :user
end

Use it in the view:

Menu.new(user: current_user).user_menu[:children] 
# => [{ href: "/users/1", title: "My Account" }]

You can also set up a helper method:

# in the ApplicationController
private
  def menu
    @menu ||= Menu.new(user: current_user)
  end
  helper_method :menu

# in the view
menu.user_menu[:children] # => [{ href: "/users/1", title: "My Account" }]

# TODO: 
# menu.sidebar_menu
# menu.all.each do |group|
#   group[:group_title]
#   ...
# end

https://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to

https://api.rubyonrails.org/classes/AbstractController/Helpers/ClassMethods.html#method-i-helper_method

List url helpers: Rails.application.routes.named_routes.helper_names

List controller helpers: ApplicationController._helper_methods

  • Related