部分传递设计用户路径
Pass the devise user path in a partial
我正在尝试使用以下信息创建侧边栏菜单:
# app/controllers/users_controller.rb
def show
@user = User.friendly.find(params[:id])
end
# config/routes.rb
get "/user/:id", to: "users#show"
我有 link 从下拉菜单到 current_user
路径:
<!-- app/views/layouts/_dropdown_menu.html.erb -->
<%= link_to "My Account", current_user %>
这是我创建侧边栏菜单的方式:
<!-- 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 class="nav-title"><%= 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 class="<%= sub_menu[:subtitle_class] %>">
<%= 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>
我有一个 SidebarMenu
模型并且我添加了 current_user
路径:
# 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
但它会引发一条错误消息:
undefined local variable or method `current_user' for SidebarMenu:Class
谁能告诉我如何解决这个问题?
这就是 Devise 设置 current_user
方法的方式:ActionView::Base
中的 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。 current_user
不是 url 助手,它 returns 是一个 User
模型实例,link_to
可以自动变成 url。
current_user
超出了 SidebarMenu
class 的范围。要修复它,只需将它作为参数传递:
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" }]
我认为,更好的方法是使用菜单 class 作为对象。它更灵活,更易于使用:
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
在视图中使用它:
Menu.new(user: current_user).user_menu[:children]
# => [{ href: "/users/1", title: "My Account" }]
您还可以设置辅助方法:
# 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
列出 url 个帮助者:Rails.application.routes.named_routes.helper_names
列出控制器助手:ApplicationController._helper_methods
我正在尝试使用以下信息创建侧边栏菜单:
# app/controllers/users_controller.rb
def show
@user = User.friendly.find(params[:id])
end
# config/routes.rb
get "/user/:id", to: "users#show"
我有 link 从下拉菜单到 current_user
路径:
<!-- app/views/layouts/_dropdown_menu.html.erb -->
<%= link_to "My Account", current_user %>
这是我创建侧边栏菜单的方式:
<!-- 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 class="nav-title"><%= 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 class="<%= sub_menu[:subtitle_class] %>">
<%= 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>
我有一个 SidebarMenu
模型并且我添加了 current_user
路径:
# 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
但它会引发一条错误消息:
undefined local variable or method `current_user' for SidebarMenu:Class
谁能告诉我如何解决这个问题?
这就是 Devise 设置 current_user
方法的方式:ActionView::Base
中的 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。 current_user
不是 url 助手,它 returns 是一个 User
模型实例,link_to
可以自动变成 url。
current_user
超出了 SidebarMenu
class 的范围。要修复它,只需将它作为参数传递:
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" }]
我认为,更好的方法是使用菜单 class 作为对象。它更灵活,更易于使用:
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
在视图中使用它:
Menu.new(user: current_user).user_menu[:children]
# => [{ href: "/users/1", title: "My Account" }]
您还可以设置辅助方法:
# 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
列出 url 个帮助者:Rails.application.routes.named_routes.helper_names
列出控制器助手:ApplicationController._helper_methods