简体   繁体   English

如何为控制器中的部分视图定义功能以在所有视图中工作? Ruby on Rails

[英]How do you define a function for partial in a controller to work in all of the views? Ruby on Rails

For example, I'm placing the partial <%= render "layouts/location" %> in views all over the site. 例如,我将部分<%= render "layouts/location" %>放置在整个网站的视图中。 I need a controller for the layout (I tried layouts_controller.rb ) so I could do 我需要一个布局控制器(我尝试过layouts_controller.rb),所以我可以

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

The partial contains the code <%= @city %>, <%= @state %> 部分包含代码<%= @city %>, <%= @state %>

This is all effectively, supposed to display the city and state of the visitor on whatever page the partial is rendered on. 这一切都是有效的,应该在呈现部分内容的任何页面上显示访问者的城市和状态。

When I do this however, and push to heroku and migrate the database, I'm served the error: An error occurred in the application and your page could not be served. 但是,当我执行此操作并推送到heroku并迁移数据库时,将收到错误消息:应用程序中发生错误,无法提供您的页面。 Please try again in a few moments. 请稍后重试。

If you are the application owner, check your logs for details. 如果您是应用程序所有者,请检查日志以获取详细信息。

So the question is, how do I define a function for a partial? 所以问题是,如何定义局部函数?

You could do this in a before filter in your application controller like so: 您可以在应用程序控制器中的before过滤器中执行此操作,如下所示:

...
before_filter :location

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

The name of the method needs to match the symbol in the before_filter call, but other than that, you can call the method whatever you want. 该方法的名称需要与before_filter调用中的符号匹配,但是before_filter ,您可以随意调用该方法。 The method must be in the ApplicationController class though. 但是,该方法必须在ApplicationController类中。

Clarification: This will get called before every request in your application and set these two instance variables for you, so in every view, you will always and automatically have access to @city and @state. 说明:这将在应用程序中的每个请求之前调用,并为您设置这两个实例变量,因此在每个视图中,您将始终自动访问@city和@state。

I feel like you can make a few improvements from the other solutions. 我觉得您可以从其他解决方案中进行一些改进。

In ApplicationController 在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

It's likely that you don't need those variables for the create, update and destroy actions, so using only: [...] seems like a good idea. 您可能不需要这些变量来进行创建,更新和销毁操作,因此only: [...]使用only: [...]似乎是个好主意。 You can add other custom methods in there. 您可以在其中添加其他自定义方法。 The main problem with that will be when your create action will fail, and you'll want to render the "edit" page. 这样做的主要问题是您的create操作将失败,并且您需要呈现“ edit”页面。 If you don't need those variables on the edit page, then everything's fine. 如果您在编辑页面上不需要这些变量,那么一切都很好。 Otherwise, you'll need to call set_location yourself: 否则,您需要自己调用set_location

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

Also, in the 30% of pages that don't need those variables, you can use skip_before_filter : 另外,在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

You should take a look at cells . 你应该看看细胞 It is an awesome, but rather unknown gem that allows you to structure your application in "cells". 这是一个了不起的但鲜为人知的宝石,它使您可以在“单元”中构建应用程序。 It might be just what you need. 这可能正是您所需要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM