2016-05-18 7 views
1

Inputhas_many :translationsのモデルの場合、どの変換行がソートされていますか?その関連付けはどのコード行でソートされていますか?

Input.includes(:translations).order("translations.value DESC") 

モデル

class Input < ActiveRecord::Base 
    has_many :translations, dependent: :destroy 
end 

class Translation < ActiveRecord::Base 
    belongs_to :input 
    belongs_to :language 
end 

# translations table schema: 
# id   :integer 
# value  :string 
# input_id :integer 
# language_id :integer 

(私は翻訳に関連付けられている8言語のための)8列が最初に翻訳の値でソートして、私は、すべての入力をリストする必要があります言語(任意に設定)。

enter image description here

答えて

1

最初の質問に答えるために、入力テーブルのすべての行がTranslationsテーブルに参加するため、結合されたすべての行は、Translationsテーブルからvalueでソートされます。

入力テーブルに対してクエリに条件を指定しないでください。入力テーブルのすべての行が使用されますが、これはあなたの意図です。

あなたはほぼ確実にjoinsを意味するときに、includesをクエリに使用しています。これらは多くの場合構文的に互換性がありますが、目的が異なるため意味的です。

includesは、具体的にはeager loadingを容易にするために提供され、一方joinsは、joining tablesをサポートすると定義されています。経験則では、クエリで結合テーブルの列のいずれかを使用する場合は、joinsを使用します。そうでない場合は、includesを使用して関連付けを熱心に読み込むことができます。

あなたが得ようとしている結果は、SQLだけではかなり困難です。ただし、入力行と関連付けを簡単に取得し、単純なRubyコレクション変換を使用して、翻訳の欠損値のプレースホルダを含め、必要な結果を得ることができます。

これを試してください:

languages = Language.all.order("name") 
inputs = Input.includes(:translations).order("id") 
translations = inputs.map do |input| 
    { 
    input.id => languages.map do |language| 
        item = input.translations.find_index {|i| i.language_id == language.id } 
        item ? nil : input.translations[item] 
       end 
    } 
end 

これはハッシュの配列が返され、そのキーとごとに供給される翻訳の8列のテーブルとしてinput.idnilは、入力のために存在しない翻訳のプレースホルダーとして使用されます。そのため、ビュー内の指示として "Translate ..."オプションを挿入することができます。これは、使用することができる方法である:

明らか
<table> 
<% inputs.each do |input| %> 
    <tr> 
    <% translation = translations[input.id] %> 
    <% translation.each do |item| %> 
     <% item %> 
      <td class="translation-available"><%= item.value %></td> 
     <% else %> 
      <td><%= link_to "Translate...", translate_input_path(input) %></td> 
     <% end %> 
    </tr> 
<% end %> 

、私はinputs配列を処理する方法をお見せするために、いくつかの構造とデザイン要素に嘲笑しました。必要に応じて、ビュー構造に合わせて変更することができます。

+0

ありがとう、入力テーブルが正常に動作します。さて、入力言語をアルファベット順に並べ替えるにはどうしたらいいですか? –

+1

コードの最初の行は 'languages = Language.all.order(" name ")'です。注文するフィールドを変更すると、ここに表示される言語の順序が変更されます。私はあなたの言語モデルが 'name'フィールドを持っていると仮定していますが、あなたの目的に合わせてここに最も適したフィールドを置くことができます。 –

2

あなたtranslationsテーブルのvalue列。これは、次のようなSQLを生成します。

SELECT "inputs"."id" AS t0_r0, "inputs"."name" AS t0_r1, ..., 
    "translations"."id" AS t1_r0, "translations"."value" AS t1_r1, ... 
FROM "inputs" 
LEFT OUTER JOIN "translations" 
    ON "translations"."input_id" = "inputs"."id" 
ORDER BY translations.value DESC // <== YOUR `.order()` method 

ご覧のとおり、順序はDBではなくRailsで行われます。したがって、注文はあなたのDB注文が何であれ可能です。

+0

しかし、1つの入力は複数の翻訳を持つことができるので、ソートアルゴリズムが使用していますか? –

+1

私は追加のメモで私の答えを更新しました。 – Uzbekjon

+1

@ViniciusFontouraはソートに* all *を使います。それぞれの "入力"は、表示するクエリで複数回表示される可能性があります。 – lurker

関連する問題