我正在开发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
答案 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_filter
。 ActiveResource::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"