2012-04-27 3 views
1

Rails 애플리케이션을 개발 중이며 ActiveResource를 사용하여 REST 서버에 요청을 보내려고합니다. 서버의 실제 URL 사이트입니다 :ActiveResource의 사이트 URL을 통한 로케일 매개 변수 전달

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

요점은 서버에 모든 통신을 위해 내가 레일 응용 프로그램 컨텍스트에서 현재의 지역을 통과 할 것입니다. 그래서 유효한 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에서 파생 된 기본 클래스를 가지며 다음과 같이 로케일을 설정할 수 있도록 모든 리소스 액세스 메서드를 재정의합니다.

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에 많은 자세한 정보와 복잡성을 부여합니다. 이 :locale을 전달하려면 ActiveResource::Base의 모든 메서드를 재정의해야합니다.

어떻게하면 더 효율적으로 할 수 있을까요? 사전

Panayotis

답변

0

당신은 MyBaseClassActiveResource::Base에서 파생 언급하지만, 코드가 ActiveRecord::Base 표시에

덕분에 - 아마도이 오타입니다.

응용 프로그램 로캘이 올바르게 설정되었는지 확인하십시오.

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의 :

app/controllers/application_controller.rb에서 : 경우에 여기에 내가 일반적으로 응용 프로그램의 국제화를 설정하는 방법은, 당신에게 유용 그런

scope "/:locale" do 
    # routes 
end 

하는 before_filter에 대한에 ActiveResource::Base.prefix을 설정 컨트롤러. 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/아래에 중첩)으로 지시하는 것뿐만 아니라 각 요청에 대해 올바르게 작동합니다.

+0

감사 오타에 대한 보정. 솔루션은 사이트를 한 번 설정하기 때문에 작동하지 않습니다. '''self.site = "...'''는 요청이 원격 자원 (REST) ​​서버로 전송 될 때마다 호출되지 않습니다. –

+0

아, 물론 알았습니다. 위의 게시물을 수정했습니다. – tiredpixel

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"