首页 > 解决方案 > 使用 Ruby eval 方法真的很危险吗?如果是,还有什么替代方法?(导轨)

问题描述

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

意见/管理员/用户/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来捕获由于守卫等导致的无效转换。

布雷克曼eval()对视图中的方法感到害怕。我不是 100% 确定它为什么会被这个困扰 - 它只是将所有eval()方法都视为邪恶吗?传递给方法 ( t) 的对象不是用户输入,它基于状态机提供的转换。我不知道这怎么可能是一个漏洞?也许这是我对一些基本概念缺乏了解......

所以真的有两个问题:

谢谢!我很感激帮助。

标签: ruby-on-railsrubyaasm

解决方案


有没有更好的方法来实现这一点?也许控制器中的某种通用转换动作已经传入了转换?看起来更干净,有兴趣听听其他人是否采用了这种方法。

类似的东西怎么样:

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

然后,在update您的方法中AdminUsersController(或admin_user_path使用patchHTTP 动词解析到的任何地方),您可以测试transition参数的存在并采取相应的行动。正如你所说,你可以包括一些开始/救援来捕捉由于守卫等导致的无效转换。

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


推荐阅读