Rails:如何将应用程序控制器变量传递到应用程序布局?

14
我试图将应用控制器中设置的变量传递到应用程序布局。
如果我使用以下内容:
@var = 'foo'

应用程序布局不知道我在说什么。

如果我使用全局变量

$var = 'foo'

我的应用程序布局可以正常工作。 但是,我的功能测试不起作用:

# application layout
# my var is an AR object
$var.name

# Stock functional test
class HomeControllerTest < ActionController::TestCase
  test "should get index" do
    get :index
    assert_response :success
  end
end

# test:functionals 
ActionView::Template::Error: undefined method `name' for nil:NilClass

我希望这个变量在应用程序布局中可用(每个页面都有)。你有什么想法?我是否需要将其作为会话变量?

更新

根据我正在阅读的其他帖子,将它们放在应用程序助手中,然后从布局调用它们被认为是最佳实践吗?

# Application helper
def get_var
   Product.first
end

# Application layout
<% @var = get_var %>
<!DOCTYPE html>
<html lang="en">
<head>
...

这种方法在我的浏览器中是可行的,并且测试也通过了。 这是最佳实践吗? 是否有更简单/更好的方法?

2个回答

21

你是否尝试使用before_filter方法,确保每个控制器都调用它并将变量传递给相应的视图?

class ApplicationController < ActionController::Base

before_filter :foo_function

def foo_function
@var = "foo"
end

end

如果@var是一个AR对象而不是字符串,你确定已经正确定义了模型名称和列名称吗?


变量正在设置而没有使用before_filter。实际上,如果我将它们设置为全局变量,应用程序布局可以看到它们。但是,a)我正在尝试避免全局变量,b)我的基本功能测试不知道它们(出于某种奇怪的原因)。 - jmccartie

1
你尝试过将它实现为一个helper_method吗?
class ApplicationController < ActionController::Base
  helper_method :foo, :foo=

  def foo
    @var ||= "foo"
  end

  def foo=(val)
    @var = val
  end
end

这与将它们放在应用程序助手中相比有什么优势?我知道这样做可以从任何地方调用它,但在这种情况下,我只需要它在应用程序布局中可用即可。 - jmccartie
如果你只需要在布局文件中使用它,两种方法都可以。这取决于方法的性质,但除非你有一个非常复杂的项目,否则这不是什么大问题。个人而言,我会将输出格式化方法及其依赖方法放在应用程序助手中,同时将其他方法保留在应用程序控制器中。 - PeterWong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接