这种 Ruby eval 方法的使用真的很危险吗?如果是,还有什么替代方法? (Rails)

Is this use of a Ruby eval method really dangerous, and if so what's the alternative? (Rails)

好的,所以我在我的 Rails 应用程序中使用 AASM 来管理我的用户模型周围的工作流。在视图层中,我想做一个小下拉菜单,显示给定用户的所有可用转换,并在单击时执行该转换,它会根据用户所处的状态动态调整。它工作正常。这是基本实现:

views/admin/users/index.html.erb:

<% user.available_transitions.each do |t| %>
  <%= link_to(t.to_s.humanize, eval("#{t}_admin_user_path(user)"), class: 'dropdown-item', :method => :post) %>
<% end %>

在路由文件中:

namespace :admin do
    ...
    resources :users do
      member do
        post 'apply'
        post 'invite_to_interview'
        post 'approve_for_training'
        ...
      end
    end
  end

每一个在控制器中都有对应的动作。真的不值得一一列出,他们只是调用适当的转换,例如 @user.invite_to_interview! 和一些 begin/rescues 来捕获由于守卫等引起的无效转换

Brakeman 对视图中的 eval() 方法很生气。我不是 100% 确定为什么它会为此烦恼 - 它只是将所有 eval() 方法视为邪恶吗?传递到方法中的对象 (t) 不是用户输入,它基于状态机提供的转换。我不知道这怎么可能是一个漏洞?也许这是我对一些基本概念缺乏理解......

所以真的有两个问题:

谢谢!感谢您的帮助。

Is there a better method for implementing this? Maybe some kind of generic transition action in the controller that has the transition passed in? Seems cleaner, interested to hear if anyone else has taken this approach.

按照以下方式行事怎么样:

<% user.available_transitions.each do |t| %>
  <%= link_to t.to_s.humanize, admin_user_path(user, transition: t), class: 'dropdown-item', method: :patch %>
<% end %>

然后,在 AdminUsersControllerupdate 方法中(或 admin_user_path 使用 patch HTTP 动词解析的任何地方),您可以测试是否存在transition 参数并据此采取行动。正如您所说,您可以包括一些 begin/rescues 以捕获由于守卫等引起的无效转换

这样一来,您对所有链接只有一个操作。