ERB 作用域:实例变量与局部变量

ERB scope: instance variable vs locals

假设我有一个带有 index 动作的控制器,我想将一些数据传递到动作的视图 (index.html.erb)。

通常,rails 方法是:@some_var = some_value

@some_var 现在随处可用(助手等...)的意义上说,以上是否增加了全局范围?如果是这样,是否更好地执行类似 locals: {some_var: some_value} 的操作?

有什么权衡取舍?

不,如果您将 @some_var = some_value 添加到索引操作,那么它只会应用于该操作。如果你想创建一个全局动作,那么你可以将它应用到 application.rb.

强烈推荐阅读http://guides.rubyonrails.org/action_controller_overview.html

但您可能特别感兴趣的是:

4.4 default_url_options You can set global default parameters for URL generation by defining a method called default_url_options in your controller. Such a method must return a hash with the desired defaults, whose keys must be symbols:

class ApplicationController < ActionController::Base   def
default_url_options
    { locale: I18n.locale }  
end end

These options will be used as a starting point when generating URLs, so it's possible they'll be overridden by the options passed in url_for calls.

If you define default_url_options in ApplicationController, as in the example above, it would be used for all URL generation. The method can also be defined in one specific controller, in which case it only affects URLs generated there.

是的,@some_var 是 "global",因为它添加到视图和助手共享的视图上下文中。所以你的控制器、视图、部分和助手都可以访问相同的 @some_var.

像这样使用实例变量是 Rails 惯例:它们只是 "like magic" 出现在您的视图和助手中,没有额外的代码。为简单起见,我建议将它用于大多数项目,尤其是刚开始时。

但是,随着您的 Rails 应用的发展,请记住以下一些其他最佳做法:

  • 尝试将您的控制器限制为仅分配一个实例变量。如果您发现自己在单个控制器操作中分配了许多实例变量,这通常表明您的控制器试图做太多事情。
  • 避免在助手中使用实例变量。这使得您的辅助方法更难在其他上下文中重用,因为它们依赖于控制器设置 "just right" 的实例变量。这可能是错误的来源。

是的,我想你已经明白了。我也更喜欢这样的局部参数,即使你是对的 Rails 建议你使用实例变量。

我认为实例变量在完整模板中(从不在部分模板中)可能没问题,尤其是当您只有其中一个与控制器或其他名称同名的实例变量时。

但总的来说,我同意你的看法。与当地人一起做没有任何缺点,除非你认为它混淆了代码,也许它会让那些期望它是 'ordinary' Rails 方式的人感到困惑。

我想有人会争辩说 Rails 模板天生就与控制器紧密耦合,本来就是这样,所以使用实例变量没什么大不了的——主要的缺点是它将您的模板与特定的控制器实现紧密耦合,但是,他们会说,这很好。我想这是一个意见,显然是 Rails' 的意见!当然,很多应用程序都是以这种方式编写的,这很好。

但是,与典型的 Rails 做事方式相反,并使用本地模板参数而不是实例变量,实际上并没有什么会妨碍您。它工作正常。我已经做到了。

我认为你愿意质疑 Rails 是正确的 -- 有时 Rails 做出了一些奇怪的选择。而且 对继续做一些不同于 Rails 似乎希望你做的事情保持谨慎是正确的,有时它 确实 会导致问题。在这种情况下,我不希望它会。