3

サイトユーザーの編集/作成ページで言語選択ドロップダウンを作成したい。

この目的のために、私はもちろんサイトを複数の言語に翻訳しました。I18n.available_languagesを使用して、次のようなロケールコードの配列を取得できます。

development environment (Rails 2.3.4)
> I18n.available_locales
   => [:en, :da]

さらに、言語モデルを作成し、それをユーザーに関連付けました。

# app/models/language.rb
class Language < ActiveRecord::Base
  has_many :users  
end

# app/models/user.rb
class User < ActiveRecord::Base
  belongs_to :language  
end

# db/schema.rb
create_table "languages", :force => true do |t|
  t.string "name"
  t.string "code"
end

create_table "users", :force => true do |t|
  t.integer  "language_id"
end

言語テーブルには、次のように、ロケールコードと母国語の言語名が含まれます。

| id  | name                | code |
------------------------------------
| 28  | Dansk               | da   |
| 29  | Nederlands          | nl   |
| 30  | English             | en   |
| 31  | Esperanto           | eo   |

次に、User new、create、editアクションに次の割り当てがあります。

# app/controllers/users_controller.rb (extract)
@available_languages = I18n.available_locales.collect {|language_code| Language.find_by_code(language_code.to_s)}

私はそのようにビューで使用します(コントローラーからの@available_languagesがパーシャルに渡されているため、'available_languages'はローカル変数です):

# app/views/users/_form.haml (extract)
= f.collection_select(:language_id, available_languages, :id, :name, {:prompt => true})

このすべての結果は、ユーザーが特定のユーザーのロケールを定義するためのロケール選択ドロップダウンを取得することです。

私の質問は次のとおりです。@available_languages割り当てをUsersControllerからLanguageモデルに移動するクリーンな方法があるので、これを短縮できます。

@available_languages = I18n.available_locales.collect {|language_code| Language.find_by_code(language_code.to_s)}

このようなものに:

@available_languages = Language.translations_available
4

3 に答える 3

13

各ymlに「locale_name」キーを追加し、独自の言語でも言語名を付けます。例えば:

es-AR.yml で

es-AR:
  locale_name: "Castellano"

en.ymlで

en:
  locale_name: "English"
于 2010-01-19T23:38:23.847 に答える
13

Dwaynemacのソリューションに基づくより完全な回答は次のとおりです。

  1. 各 yml ファイルにロケール名を持つキーを追加します。たとえば、en.yml では次のようになります。

    en:
      language: English
    

    そしてes.ymlで:

    es:
      language: Español
    
  2. ロケールとロケール名のペアの配列を作成するヘルパー メソッドを (たとえば /app/helpers/application_helper.rb に) 追加します。

      def locale_name_pairs
        I18n.available_locales.map do |locale|
          [I18n.t('language', locale: locale), locale.to_s]
        end
      end
    
  3. フォームlocale_name_pairsで選択ドロップダウンを作成するために使用します。

    f.select :locale, options_for_select(locale_name_pairs, @user.locale)
    

怠け者への注意:ステップ 2 をスキップしたい場合は、ステップ 3 で次のワンライナーを使用できます。 f.select :locale, options_for_select(I18n.available_locales.map{ |locale| [I18n.t('language', locale: locale), locale.to_s] } , @user.locale)

于 2013-06-25T06:52:02.770 に答える
5

あなたはいくつかの面白いことをしているように私には思えます。まず、次のような問題があります。

I18n.available_locales.collect {|language_code| Language.find_by_code(language_code.to_s)}

この設定により、使用可能なロケールごとに 1 つの SQL クエリが生成されます。さらに、すべてのロケールにI18n.available_locales対応するLanguageオブジェクトがあり、その逆の場合、このコードは少し不要に思えます。次のようにすることもできます。

Language.find(:all) # or even Language.all

何らかの理由でそれらが直接マップされない場合は、代わりにこれを使用できます。

Language.all(:conditions => { :code => I18n.available_locales })

より詳細な形式では、次と同等です。

Language.find(:all, :conditions => ["code IN (?)", I18n.available_locales])

これにより、コードが I18n.available_locales にリストされているすべての言語が検索されます。このメソッドへのショートカットが必要な場合は、named_scopes を使用できます。

class Language < ActiveRecord::Base
  has_many :users

  named_scope :translation_available, :conditions => { :code => I18n.available_locales }
end

これにより、次のように呼び出すことができます。

Language.translation_available

これがあなたが望んでいたことだと思います。

于 2009-10-05T13:59:22.643 に答える