我有一个应用程序布局,其中包含登录用户编辑其个人资料的链接。最初是这样的:
<%= link_to "Settings", edit_user_path(current_user) %>
但后来我需要不同类型的用户,我最终得到了这个:
<%= link_to "Settings", send("edit_#{current_user.type.downcase}_path", current_user) %>
Users表上的“type”列用于STI,我可以神奇地拥有User(Model)类的子类,这对我来说非常方便。
我也有UsersController的子类,所以我会为每种类型提供“edit_ TYPE _path”路径。
有更好的方法可以做到这一点,还是我做得很好?
答案 0 :(得分:2)
polymorphic网址助手可以在这里完成工作:
edit_polymorphic_path(current_user)
应该做的伎俩。如果您确实发现自己需要使用send
,那么(如果可能)请尝试使用public_send
。顾名思义,这只会调用公共方法。
旁注type.downcase
不太正确 - 如果类名是FooBar,那么路由名称将是edit_foo_bar_path
而不是edit_foobar_path
。 underscore
变形更接近您的需求
答案 1 :(得分:0)
polymorphic path
建议就是您所需要的。
您也可以使用eval
-
eval("edit_#{current_user.type.downcase"}_path(#{current_user.id})")
......虽然显然polymorphic_path
更受欢迎。
由于系统的结构,我觉得答案是合适的(这在评论中被选中)。
STI的东西很棒 - 我觉得它不应该像我们应该的那样。但是,关于编辑您的个人资料,我认为您不需要每次都更改控制器操作。
当然,你可能,如果你这样做,那么我想你知道你在做什么。
但是,如果是我,我会将它全部保存在users
控制器中,即使你有不同的路径可以到达那里。如果需要,您可以随时将功能推断为助手等:
#config/routes.rb
resources :users, only: [:edit, :update], path: "", path_names: {edit: "profile", update: "profile" }
这将产生以下网址:
# GET url.com/profile
# PATCH url.com/profile
现在...
这里重要的是这句话:
修改 他们的 个人资料
这是每个用户的基础。
如果您需要不同的功能,则必须使用单独的控制器,但由于您总是会引导用户他们的配置文件,我认为您不需要不过是一个控制器。
你可以做这样的事情:
#app/models/user.rb
class User < ActiveRecord::Base
def is? is_type
type == is_type
end
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def edit
current_user.is?(:admin) ? change_admin : change_user
end
private
change_admin
#logic
end
change_user
#logic
end
end
这假设您的用户在功能上非常相似。