在视图和模型中可用的language_id的全局变量

时间:2013-06-11 08:01:14

标签: ruby-on-rails ruby-on-rails-3 model global-variables

我正在尝试在控制器,视图和模型中共享会话变量。

使用以下代码,它在控制器和视图中工作:

class ApplicationController < ActionController::Base
    protect_from_forgery
    helper_method :best_language_id

    # Returns the ID of the language to use to display the description.
    def best_language_id
        @best_language_id ||= session[:best_language_id]
        @best_language_id ||= current_project.default_language.id
        return @best_language_id
   end
end

但是我无法从模型中调用它。

我希望能够在控制器,视图和一个模型中调用best_language_id,以便在找不到翻译时获得best_language_id的回退。

我模型中的示例(不工作):

class Point < ActiveRecord::Base
    # Retuns the attached word in the given language if exists. 
    # Otherwise, falls back on another translation
    def word(preffered_language_id)
        word = Word.find(:translation_id => self.translation_id, :language_id => preffered_language_id)
        if word.blank?
            word = translations.where(:translation_id => self.translation_id, :language_id => best_language_id)
        end
        return word
    end
end

我知道该模型不应该包含applicationcontroller方法调用,但是如何在控制器和模型之间共享我的best_language_id呢?

编辑:使用i18n不是问题。翻译不是固定字符串,而是数据库中的变量。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我建议你改变这种情况,将best_language_id存储在模型中作为类访问器,然后你可以从控制器设置并获取它,它仍然可以在模型中使用。

class Point < ActiveRecord::Base
  cattr_accessor :best_language_id # to store the variable
end

# Persist the content of that variable at the start of every action
class ApplicationController < ActionController::Base 
  before_filter :set_best_language

  def set_best_language
    Point.best_language_id = session[:best_language_id]
    Point.best_language_id ||= current_project.default_language.id
  end
end

# Use the variable in a controller
class SomeOtherController < ActionController::Base
  def show
    @best_language = Language.find(Point.best_language_id)
    ...
  end
end

# Use the variable in a model
class SomeOtherController < ActiveRecord::Base
  def some_method
    best_language = Language.find(Point.best_language_id)
    ...
  end
end

答案 1 :(得分:1)

在rails应用程序中,config / application.rb中有一个基本模块。它应该以您的申请命名。让我们说它叫做MyApp。你可以做的是定义两个这样的方法:

module MyApp
  ...
  def self.language_id=(value)
    @language_id = value
  end

  def self.language_id
    @language_id ||= 'en' # default vaule
  end
  ...
end

然后,在app / controllers / application_controller.rb中添加一个像这样的before_filter:

before_filter :language
def language
  MyApp.language_id = session[:language_id] if session[:language_id] 
end

然后,从应用程序的所有位置,您都可以通过

访问该值
MyApp.language_id

不用说这种方法不是线程安全的,所以不要在线程环境中使用它。