在ActiveResource上通过站点URL传递语言环境参数

时间:2012-04-27 12:16:19

标签: ruby-on-rails-3 default activeresource

我正在开发Rails应用程序,我想使用ActiveResource将请求发送到REST服务器。服务器的实际URL站点是:

http://foo.com/api-v1.0

重点是,对于每次与服务器的通信,我都想在Rails应用程序上下文中传递当前的语言环境。所以有效的URL调用是:

e.t.c。

所以,我正在关注可怜的ActiveResource文档,并按如下方式定义我的资源类:

class MyClass < ActiveResource::Base
  self.site = "http://foo.com/api-v1.0/:locale
end

然后在我的应用程序控制器上,我有这样的东西,例如当得到所有人时:

MyClass.all(:params => {:locale => I18n.locale})

工作正常。

问题是控制器代码变得非常冗长。我不得不在我正在访问的每个资源上传递:params => {:locale => I18n.locale}

为了避免这种情况,我决定有一个派生自ActiveResource :: Base的基类,并以这种方式覆盖所有资源访问方法,以便我可以设置:locale。所以代码变成了:

class MyBaseClass < ActiveResource::Base
  self.site = "http://foo.com/api-v1.0/:locale"

  def self.all
    super(:params => {:locale => I18n.locale})
  end
end

class MyClass < MyBaseClass
end

并在我的应用程序控制器中:

MyClass.all

就够了。

然而,这给MyBaseClass带来了许多冗长和复杂性。我必须覆盖ActiveResource::Base的所有方法才能传递此:locale

有什么线索我怎样才能更有效地做到这一点?

提前致谢

Panayotis

2 个答案:

答案 0 :(得分:0)

您提到MyBaseClass来自ActiveResource::Base,但代码显示ActiveRecord::Base - 可能是这是一个错字。

确保正确设置应用程序区域设置;如果它对你有用,这就是我通常为应用程序设置I18n的方法:

app/controllers/application_controller.rb

before_filter :set_locale

def set_locale
  I18n.locale = params[:locale] || I18n.default_locale
end

def default_url_options(options={})
  {
    :locale => I18n.locale
  }
end

config/routes.rb

scope "/:locale" do
  # routes
end

然后,在控制器的ActiveResource::Base.prefix中设置before_filterActiveResource::Base.site也可以设置在同一个地方,也可以设置在模型上。默认情况下,模型名称(小写)用作指定站点的资源;这些可以用ActiveResource::Base.element_name覆盖。 ActiveResource::Base.prefix可用于为每个资源路径添加前缀。因此,在整个应用程序中实现您的示例的一种方法(但这可能只是一个非应用程序控制器)将是:

app/controllers/application_controller.rb

before_filter :setup_activeresource

def setup_activeresource
  ActiveResource::Base.site = "http://foo.com/api-v1.0"
  ActiveResource::Base.prefix = "#{I18n.locale}/"
end

实验表明,这为每个请求正确设置了语言环境,并指向正确的远程资源(嵌套在/:locale /)下。

答案 1 :(得分:0)

如果你在应用程序中使用ActiveResource的所有地方总是想要这种行为:覆盖低级 ActiveResource :: Connection.request 方法以填充语言环境字符串:

class ActiveResource::Connection
  alias :original_request :request
  def request(method, path, *arguments)
    original_request(method, changed_path, *arguments)
  end
end

坚持使用初始化程序。

您的字符串替换会有所不同,但这适用于您的示例:

1.9.2p290 :066 >   path = "http://foo.com/api-v1.0/people"
 => "http://foo.com/api-v1.0/people" 
1.9.2p290 :067 > locale = "fr"
 => "fr" 
1.9.2p290 :068 > changed_path = path.sub(/http:\/\/foo.com\/api-v1.0\//, "http://foo.com/api-v1.0/#{locale}/")
 => "http://foo.com/api-v1.0/fr/people"