我的路线如下:
scope ":department", department: /admin|english|math/, defaults: { department: 'admin' }
是否可以使此路线的默认部门基于current_user.department.name
?
如果无法做到这一点,那么解决问题的另一种方法是什么。问题是除非另有说明,否则我希望所有链接都默认为当前范围。我目前正在很多地方做以下事情:
# links to /math/students
link_to 'students', students_path(department: current_user.department.name.downcase)
答案 0 :(得分:6)
如果我理解正确,你想要写的是:
link_to 'students', students_path
并根据当前用户自动设置部门选项。
这是一个解决方案,就像其他一些提供的解决方案:为每个需要部门的路线定义帮助器。但是,我们可以通过编程方式执行此操作。
我们走了:
app/helpers/url_helper.rb
module UrlHelper
Rails.application.routes.routes.named_routes.values.
select{ |route| route.parts.include?(:department) }.each do |route|
define_method :"department_#{route.name}_path" do |*args|
opts = args.extract_options!
if args.size > 0
keys = route.parts - [:department]
opts.merge!(Hash[*keys.zip(args).flatten])
end
opts.reverse_merge!(department: current_user.department.name.downcase)
Rails.application.routes.url_helpers.send(:"#{route.name}_path", opts)
end
end
end
现在,对于每个路径都有department_students_path
路径段的:department
辅助方法。这些工作就像students_path
一样 - 您可以传入opts,甚至可以显式设置:department
,它将覆盖默认值。并且他们会及时了解您routes.rb
的更改,而无需维护它。
您甚至可以将它们命名为与原始助手相同,即
define_method :"#{route.name}_path"
不必用department_
作为前缀 - 我没有这样做,因为我宁愿避免命名这样的碰撞。我不确定它是如何工作的(当从视图模板调用方法时,哪种方法会赢得方法查找),但你可能会研究它。
您当然可以针对_url
辅助方法重复此块,因此除了_path
之外,您还可以使用这些方法。
要在控制器和视图中使用帮助程序,只需include UrlHelper
中的ApplicationController
。
所以我认为这符合您的标准:
:department
的路径调用辅助方法,默认为current_user
的部门,这样您就不必每次都明确指定。:department
段的命名路径,因此您无需维护它们。department_student_path(@student)
。但是,一个限制是,如果要覆盖部门,则需要在最终的opts哈希(department_student_path(@student, department: 'math')
)中执行此操作。再说一次,在这种情况下你可以随时做student_path('math', @student)
,所以我认为这不是一个限制。答案 1 :(得分:1)
路线约束可以接受一个proc,所以你可以通过以下“hack”来解决这个问题:
concern :student_routes do
# all your routes where you want this functionality
end
# repeat this for all departments
scope ":department", constraints: lambda{|req| req.session[:user_id] && User.find(req.session[:user_id]).department.name.downcase == "english"}, defaults: { department: 'english' } do
concerns :student_routes
end
路线问题是导轨4的一项功能。如果您不使用导轨4,您是否可以获得此宝石的功能:https://github.com/rails/routing_concerns。
您也可以将学生的所有路线复制到所有范围。
答案 2 :(得分:0)
您可以使用
link_to 'students', polymorphic_path([current_user.department.name.downcase, :students])
这将调用
math_students_path
所以上班我觉得你应该添加你的路线
scope ':department', as: 'department' do
...
as
键生成以下形式的帮助:department_something_path
由于该行太长,您可以将其提取给帮助者
# students path taking into account department
def students_path!(other_params = {}, user = current_user)
polymorphic_path([user.department.name.downcase, :students], other_params)
然后您将在您的观点中使用
link_to 'students', students_path!
答案 3 :(得分:0)
使用嵌套路由怎么样?您可以通过以下方式实现此目的:
resources :departments do
resources :students
end
如果您想使用友好的网址(例如“数学”而不是ID),可以将以下内容添加到部门模型中:
# in models/department.rb
def to_param
name.downcase
end
记住每个部门的名称必须是唯一的。 Ryan B对此提出了railscast。你也可以使用像friendly id这样的宝石。
您现在可以在视图中添加以下内容:
# links to /math/students
link_to 'students', department_students_path(current_user.department)
如果你经常使用它,那么创建一个帮手:
# helpers/student_helpers.rb
def students_path_for_current_user
department_students_path(current_user.department)
end
# in view
link_to 'students', students_path_for_current_user
答案 4 :(得分:0)
我最终在ApplicationController
中使用:
def default_url_options(options={})
{department: current_user.department.name}
end
路径助手将填充自动填写:department
参数然后...