1

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

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

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

ETC

因此,我正在关注较差的 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来传递 this :locale

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

提前致谢

帕纳约蒂斯

4

2 回答 2

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" 
于 2012-09-28T16:22:37.857 回答
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_nameActiveResource::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/ 下)。

于 2012-04-27T21:17:34.080 回答