17

Tôi chỉ nhận ra rằng Rails cách khuyến khích để thiết lập miền địa phương trong điều khiển của bạnTại sao cài đặt ngôn ngữ trong Rails hoạt động như toàn cầu (khi sử dụng Thin)?

before_filter :set_locale 

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

đặt locale trên toàn cầu. Các mã trên hoạt động, nhưng tôi tự hỏi là default_locale thực sự mặc định nếu bạn phải gõ nó một cách rõ ràng?

gì tôi mong đợi là phải có một miền địa phương theo yêu cầu (như chúng tôi có phiên theo yêu cầu) và làm một cái gì đó như:

def set_locale 
    locale = params[:locale] if params[:locale] 
end 

Và khi I18n.default_locale được sử dụng bởi mặc định khác. Điều này sẽ phù hợp với lý tưởng là miền địa phương tùy chọn trong đường dẫn:

# config/routes.rb 
scope "(:locale)", :locale => /en|nl/ do 
    resources :books 
end 

Còn bây giờ nếu vì một lý do tôi bỏ qua thiết lập miền địa phương trong một số hành động nó sử dụng ngôn ngữ thiết trong yêu cầu trước đó mà có thể là từ một người dùng khác!

Và không có điều kiện chủng tộc tiềm năng nào vì một yêu cầu có thể thay đổi toàn cầu I18n.locale trong khi yêu cầu khác (đã đặt ngôn ngữ khác trước đó) đang ở giữa hiển thị?


UPDATE: Một số chi tiết tôi thấy bây giờ, từ documentstion i18n:

Thiết lập miền địa phương hiện tại giả trên toàn cầu, tức là trong băm Thread.current def locale = (locale)

Bây giờ tôi muốn hiểu nếu mọi yêu cầu là một chuỗi riêng biệt.


CẬP NHẬT 2: Xem câu trả lời của tôi để được giải thích.

Trả lời

12

Vì vậy, bây giờ là câu trả lời cuối cùng. TL; DR Đặt ngôn ngữ chỉ hoạt động ở chế độ toàn cầu khi bạn sử dụng máy chủ web có ren, như Thin và Puma.

Như tôi đã đề cập, I18n.locale=

Thiết lập miền địa phương hiện tại giả trên toàn cầu, ví dụ trong bài viết.băm hiện tại

Vì vậy, nó được cho là theo yêu cầu và nó hoạt động theo cách này trong Webrick và Unicorn.

Nhưng nếu bạn sử dụng máy chủ web luồng như Thin hoặc Puma, có vẻ như chuỗi tồn tại lâu hơn và giá trị được giữ nguyên cho các yêu cầu trong tương lai, cho đến khi được thay đổi rõ ràng. Nơi tôi học được đó là từ đá quý mới Steve Klabnik của request_store:

Nếu bạn cần trạng thái toàn cầu, bạn đã có thể đạt được cho Thread.current.

<...>

Vì vậy, người đang sử dụng những fancy luồng các máy chủ web, giống như mỏng hoặc Puma. Nhưng nếu bạn sử dụng Thread.current, và bạn sử dụng một trong những máy chủ đó, hãy cẩn thận! Giá trị có thể bám sát lâu hơn bạn mong đợi và điều này có thể gây ra lỗi.

+0

Tôi đang gặp vấn đề tương tự, nhưng tôi đang sử dụng Unicorn! Bất kỳ ý tưởng làm thế nào để giải quyết điều này? cảm ơn –

+0

Tôi nghĩ rằng khi bạn nói "I18n.set_locale", bạn thực sự có nghĩa là "I18n.locale =" phải không? http://www.rubydoc.info/github/svenfuchs/i18n/I18n/Config:locale= – lulalala

+0

Bạn nói đúng, cảm ơn bạn đã sửa. – khustochka

2

Mã được khuyến nghị từ trên cao không đặt ngôn ngữ trên toàn cầu mà nó đặt theo yêu cầu.

before_filter :set_locale 

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

Mã thường được đặt trong BaseController như vậy trước khi mỗi trang hiển thị nó được kích hoạt và đặt. Không có điều kiện chủng tộc vì mỗi trang sẽ kích hoạt mã này và miền địa phương I18n sẽ được tính toán ở đó. Bạn có thể mở rộng điều này để cho phép tìm kiếm vị trí của người dùng, so với ngôn ngữ phiên, so với thông số yêu cầu, hơn là sử dụng tiếng Anh.

def set_locale 
    I18n.locale = @user.locale || session[:locale] || params[:locale] || :en 
end 

Nói cách khác nếu bạn đặt cục bộ trên một trang, hãy nói điều khiển chính về tiếng Đức và vào bảng điều khiển, bạn sẽ thấy ngôn ngữ mặc định (tiếng Anh). Vì thay đổi không phải là toàn cầu. Đó là lý do tại sao mã được đặt trong bộ điều khiển cơ sở. Hy vọng nó có ý nghĩa.

+1

'I18n' là mô-đun chung và' I18n.locale = 'thay đổi trạng thái của nó. Tôi đồng ý rằng cách đề xuất đặt ngôn ngữ rõ ràng cho mọi yêu cầu qua 'before_filter' hoạt động như mong đợi nói chung. Tôi vẫn tự hỏi nếu các yêu cầu Rails có thể chạy đồng thời trong các luồng khác nhau - nếu có, tôi thấy có thể yêu cầu 1 bộ 'I18n.locale', sau đó yêu cầu 2 đặt' I18n.locale' khác, sau đó yêu cầu 1 bắt đầu hiển thị bằng miền địa phương mới (không chính xác). Xin lỗi nếu tôi nhận được câu trả lời của bạn sai. – khustochka

Các vấn đề liên quan