如何在控制器中定义部分函数以在所有视图中工作? Ruby on Rails

时间:2012-04-11 19:53:35

标签: ruby-on-rails ruby-on-rails-3 model-view-controller partial-views

例如,我将部分<%= render "layouts/location" %>放置在整个网站的视图中。我需要一个布局控制器(我试过layouts_controller.rb)所以我可以做

def _location
    @city = request.location.city
    @state = request.location.state
  end

部分包含代码<%= @city %>, <%= @state %>

这一切都是有效的,应该在部分呈现的任何页面上显示访问者的城市和状态。

但是当我这样做,并推送到heroku并迁移数据库时,我遇到了错误: 应用程序中发生错误,无法提供您的页面。请稍后再试。

如果您是应用程序所有者,请查看日志以获取详细信息。

所以问题是,如何为部分函数定义函数?

3 个答案:

答案 0 :(得分:3)

您可以在应用程序控制器中的before过滤器中执行此操作,如下所示:

...
before_filter :location

def location
    @city = request.location.city
    @state = request.location.state
end

方法的名称需要与before_filter调用中的符号匹配,但除此之外,您可以随意调用该方法。该方法必须在ApplicationController类中。

澄清:这将在您的应用程序中的每个请求之前调用,并为您设置这两个实例变量,因此在每个视图中,您将始终自动访问@city和@state。

答案 1 :(得分:2)

我觉得你可以从其他解决方案中做一些改进。

在ApplicationController中

class ApplicationController < ActionController::Base
    before_filter :set_location, only: [:index, :show, :edit]

    def set_location
      @city = request.location.city
      @state = request.location.state
    end
end

您可能不需要这些变量用于创建,更新和销毁操作,因此使用only: [...]似乎是个好主意。您可以在其中添加其他自定义方法。 问题的主要问题是当您的create操作失败,并且您想要呈现“编辑”页面时。如果您在编辑页面上不需要这些变量,那么一切都很好。否则,您需要自己致电set_location

def create
    @lala = Lala.new(...)
    @lala.save
    set_location if @lala.errors.any?
    respond_with @lala
end

此外,在30%不需要这些变量的网页中,您可以使用skip_before_filter

 class BlogsController < ApplicationController
    #assume you dont need those variables in your blog

    skip_before_filter :set_location # you can also use only: [:index, ...] here
 end

答案 2 :(得分:1)

你应该看看cells。它是一个非常棒但却未知的宝石,它允许您在“单元格”中构建应用程序。这可能正是你所需要的。