如何合并 rails 中的 ActiveRecord 查询结果?
How to combine ActiveRecord query results in rails?
我的 Skill 模型需要 2 组值来验证业务:
- 一个来自附加的 ValuesList 对象
- 其他来自与质量相关的附加值列表
模型如下所示:
class Value < ApplicationRecord
belongs_to :values_list
end
class ValuesList < ApplicationRecord
has_many :values, inverse_of: :values_list, dependent: :delete_all
has_many :skills
# Extra values for missing answer (quality)
has_many :skills_values_lists, foreign_key: "values_list_id"
has_many :referents, class_name: "Skill", through: :skills_values_lists
end
class Skill < ApplicationRecord
belongs_to :values_list
# Extra values for missing answer (quality)
has_many :skills_values_lists, foreign_key: "skill_id"
has_many :references, class_name: "ValuesList", through: :skills_values_lists
accepts_nested_attributes_for :skills_values_lists, reject_if: :all_blank, allow_destroy: true
end
感谢这个,我可以查询附加到技能的常规值:
@regular_values = @skill.values_list.values
(returns 一个 ActiveRecord::Associations::CollectionProxy 对象),
以及来自多个值列表的额外值:
@extra_values = @skill.references.map {|vl| vl.values}
(returns 一个包含 1 个 ActiveRecord::Associations::CollectionProxy 对象的数组)。
我想将这 2 个结果合并到一个对象中,以便在经典的 .each 循环中显示所有可用值的列表。
如何实现?
您可以使用单个查询来获取遍历值与 values_list 以及 values_list 和技能之间的关联的值:
Value.joins(values_list: :skills).where(skills: { id: skill_id })
这个答案可能不是最好的,但它解决了我的问题。
处理 2 种类型的对象时我发现:
- 将数组添加到集合代理会尝试更新源 table =>
@all_values = @regular_values << @extra_values
- 将集合代理添加到数组 returns 包含所有数据的集合数组 =>
@all_values = @extra_values << @regular_values
选择选项 2,我可以通过嵌套循环列出值:
<table class="table table-align-top">
<thead>
<tr>
<th class="col-min-nw"><%= t('Code') %></th>
<th class="col-min-nw"><%= t('Value') %></th>
<th><%= t('Description') %></th>
<th class="col-min-nw"><%= t('UpdatedAt') %></th>
</tr>
</thead>
<tbody>
<% @all_values.each do |value_set| %>
<% value_set.each do |value| %>
<tr>
<td class="no-wrap"><%= value.code %></td>
<td class="no-wrap"><%= translation_for(value.name_translations) %></td>
<td class="text-justify text-sm"><%= sanitize translation_for(value.description_translations) %></td>
<td class="text-right"><%= format_date(value.updated_at) %></td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
希望有人能提出更聪明的建议。
我的 Skill 模型需要 2 组值来验证业务:
- 一个来自附加的 ValuesList 对象
- 其他来自与质量相关的附加值列表
模型如下所示:
class Value < ApplicationRecord
belongs_to :values_list
end
class ValuesList < ApplicationRecord
has_many :values, inverse_of: :values_list, dependent: :delete_all
has_many :skills
# Extra values for missing answer (quality)
has_many :skills_values_lists, foreign_key: "values_list_id"
has_many :referents, class_name: "Skill", through: :skills_values_lists
end
class Skill < ApplicationRecord
belongs_to :values_list
# Extra values for missing answer (quality)
has_many :skills_values_lists, foreign_key: "skill_id"
has_many :references, class_name: "ValuesList", through: :skills_values_lists
accepts_nested_attributes_for :skills_values_lists, reject_if: :all_blank, allow_destroy: true
end
感谢这个,我可以查询附加到技能的常规值:
@regular_values = @skill.values_list.values
(returns 一个 ActiveRecord::Associations::CollectionProxy 对象),
以及来自多个值列表的额外值:
@extra_values = @skill.references.map {|vl| vl.values}
(returns 一个包含 1 个 ActiveRecord::Associations::CollectionProxy 对象的数组)。
我想将这 2 个结果合并到一个对象中,以便在经典的 .each 循环中显示所有可用值的列表。
如何实现?
您可以使用单个查询来获取遍历值与 values_list 以及 values_list 和技能之间的关联的值:
Value.joins(values_list: :skills).where(skills: { id: skill_id })
这个答案可能不是最好的,但它解决了我的问题。
处理 2 种类型的对象时我发现:
- 将数组添加到集合代理会尝试更新源 table =>
@all_values = @regular_values << @extra_values
- 将集合代理添加到数组 returns 包含所有数据的集合数组 =>
@all_values = @extra_values << @regular_values
选择选项 2,我可以通过嵌套循环列出值:
<table class="table table-align-top">
<thead>
<tr>
<th class="col-min-nw"><%= t('Code') %></th>
<th class="col-min-nw"><%= t('Value') %></th>
<th><%= t('Description') %></th>
<th class="col-min-nw"><%= t('UpdatedAt') %></th>
</tr>
</thead>
<tbody>
<% @all_values.each do |value_set| %>
<% value_set.each do |value| %>
<tr>
<td class="no-wrap"><%= value.code %></td>
<td class="no-wrap"><%= translation_for(value.name_translations) %></td>
<td class="text-justify text-sm"><%= sanitize translation_for(value.description_translations) %></td>
<td class="text-right"><%= format_date(value.updated_at) %></td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
希望有人能提出更聪明的建议。