该行代码中排序的是哪个关联?
Which association is sorted in that line of code?
如果 Input
模型 has_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 种语言)按第一种语言(任意设置)的翻译值排序。
您的 translations
table 的 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
如您所见,排序是在数据库中完成的,而不是 Rails。因此,排序将是您的数据库排序。
为了回答您的第一个问题,您输入 table 的所有行都用于连接翻译 table,因此所有连接的行都将按 value
排序来自翻译 table.
由于您没有为输入 table 的查询提供任何 where
条件,因此使用了输入 table 中的所有行,这听起来像是您的意图.
您在查询中使用的是 includes
,而您几乎肯定是指 joins
。虽然它们在许多情况下在语法上可以互换,但它们在语义上用于不同的目的。
includes
是专门为了方便eager loading, whereas joins
is defined to support joining tables而设置的。经验法则是,如果您想在查询中使用连接的 table 中的任何列,请使用 joins
,否则,您可以使用 includes
来预先加载关联。
仅 SQL 很难获得您想要的结果。但是,您可以轻松获取输入行和关联,并使用简单的 Ruby 集合转换来获取所需的结果,包括 Translations 中缺失值的占位符。
试试这个:
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
这将 return 一个散列数组,它将 input.id
作为键,并为每个散列提供 8 列 table 翻译。 nil
用作输入不存在的翻译的占位符,因此您可以将其用作视图中插入 "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
数组;您可以根据需要调整它以适合您的视图结构。
如果 Input
模型 has_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 种语言)按第一种语言(任意设置)的翻译值排序。
您的 translations
table 的 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
如您所见,排序是在数据库中完成的,而不是 Rails。因此,排序将是您的数据库排序。
为了回答您的第一个问题,您输入 table 的所有行都用于连接翻译 table,因此所有连接的行都将按 value
排序来自翻译 table.
由于您没有为输入 table 的查询提供任何 where
条件,因此使用了输入 table 中的所有行,这听起来像是您的意图.
您在查询中使用的是 includes
,而您几乎肯定是指 joins
。虽然它们在许多情况下在语法上可以互换,但它们在语义上用于不同的目的。
includes
是专门为了方便eager loading, whereas joins
is defined to support joining tables而设置的。经验法则是,如果您想在查询中使用连接的 table 中的任何列,请使用 joins
,否则,您可以使用 includes
来预先加载关联。
仅 SQL 很难获得您想要的结果。但是,您可以轻松获取输入行和关联,并使用简单的 Ruby 集合转换来获取所需的结果,包括 Translations 中缺失值的占位符。
试试这个:
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
这将 return 一个散列数组,它将 input.id
作为键,并为每个散列提供 8 列 table 翻译。 nil
用作输入不存在的翻译的占位符,因此您可以将其用作视图中插入 "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
数组;您可以根据需要调整它以适合您的视图结构。