在 Rails 控制器中使用全局变量是否有更好的替代方法?

Is there a better alternative to using global variables in a Rails controller with partials?

我听说在 Ruby 中使用以美元符号开头的全局变量被认为是不好的做法。 Rails 控制器也是如此吗?

例如,我有一个 Web 应用程序,它使用一系列在连续阶段呈现的分部视图。第一阶段的用户输入从参数中获取并放入全局变量中,以便每个后续方法都可以访问它。这些后期阶段需要轻松访问用户在早期阶段所做的选择。

routes.rb

post 'stage_one_form' => 'myexample#stage_two_form'
post 'stage_two_form' => 'myexample#stage_three_form'
post 'stage_three_form' => 'myexample#stage_four_form'

myexample_controller.rb

def stage_two_form
   $stage_one_form_input = params[:stage_one_form_input]
end

...

def stage_four_form
   @stage_four_displayed_info = $stage_one_form_input + "some other stuff"
end

这只是一个虚拟的例子,但在这里使用全局变量似乎比我原来的方法要优雅得多,我原来的方法是在每个阶段通过使用隐藏在客户端和服务器之间来回传递信息字段。

全局变量是否合适,或者有更好的方法吗?

您可以将它们放入 config/application.rb 或您的 config.yml 文件中。

config.your_variable = 'something'

然后从您的应用程序内部调用它

<%= Rails.configuration.your_variable %>

或者您可以将其放入控制器中:

class Foo
  MY_VARIABLE = 'something'
end

然后在你的视图中调用它:

<%= Foo::MY_VARIABLE %>

或者您可以将其放入控制器的方法中并定义一个助手:

class FooController
  def my_variable
    'something'
  end
  helper_method :my_variable
end

有关 config.yml 的更多信息,请点击此处:Best way to create custom config options for my Rails app?

..但如果您需要在不同阶段访问一个变量,您可能希望将其转储到控制器中的会话变量中:

session[:stage] = 'something'

稍后使用 session[:stage] 访问它 然后你可以在进程再次启动时清除它:

session[:stage] = nil

如果你想存储第一阶段的输入并在第二阶段使用,你就是在做一个向导。您考虑使用 session 或更强大的东西来存储信息,而不是@NickM 所述的配置或模型。

更多信息:

Rails Multi-Step Form without Wizard Gem

http://railscasts.com/episodes/217-multistep-forms

附加信息...

您在此处对这些全局变量所做的操作在您使用应用程序服务器的生产部署中不起作用。在这些环境中,您需要多个进程(或线程),以便可以同时为您站点的多个访问者提供服务。

有了这两个你会遇到两个问题:

  1. 为一位访问者设置变量将影响下一位访问者(即使是不同的人)的体验process/thread。
  2. 一个相关的问题是,完全不能保证单个访问者在他们的下一个请求中由同一进程提供服务,因此为他们的第二个请求提供服务的 process/thread 可能不会拥有全局从他们的第一个请求中设置的变量。

总而言之,混乱,使用 session - 正是它的用途。