[英]In Ruby on Rails, how do I query for items that have no associated elements in a has_many :through relationship
[英]How can I add sorting while looping through distinct associated elements in Rails?
我有一个模拟邮票收集的测试应用程序。 有一个邮票目录,用户可以添加到收藏中。 CollectionItem model 有一堆belongs_to:
belongs_to :stamp
belongs_to :issue
belongs_to :user
belongs_to :country
在集合索引视图上,有一个以级联方式列出的所有集合项的列表。
国家:发行:邮票。 发行:邮票。 发行:邮票。 国家:...等
@my_collection_countries = CollectionItem.where(user: current_user).select(:country_id).distinct(:country)
使用这种方法可以按预期工作。
<% @my_collection_countries.each do |collection_item| %>
<%= link_to collection_item.country.name, country_path(collection_item.country) %>
<% collection_item.class.where(user: current_user, country_id: collection_item.country).select(:issue_id).distinct(:issue).each do |issue| %>
<%= link_to issue.issue.name, issue.issue %>
<% issue.class.includes(:stamp).where(user: current_user, country: collection_item.country, issue: issue.issue).select(:stamp_id).distinct(:stamp).order('stamps.name asc').each do |stamp| %>
<%= link_to stamp.stamp.name, stamp.stamp %>
<% end %>
<% end %>
<% end %>
但我相信我做错了什么,因为当我尝试以与邮票相同的方式订购问题或国家时,它们会多次显示,而distinct
的没有帮助。
我能想到的解决此问题的最佳方法是使用#group_by
,这是一种 ruby 方法,它遍历集合并返回{thing_being_grouped_by: [things_that_have_that_characteristic]}
形式的 hash 。 因此,在您的情况下,我们可以使用:
@my_collection_countries = CollectionItem.where(user: current_user).group_by(&:country).sort_by { |country,_| country.name }
<% @my_collection_countries.each do |country, xs| %>
<%= link_to country.name, country_path(country) %>
<% xs.group_by(&:issue).each do |issue, ys| %>
<%= link_to issue.name, issue %>
<% ys.group_by(&:stamp).sort_by { |stamp,_| stamp.name }.each do |stamp, zs| %>
<%= link_to stamp.name, stamp %>
<% end %>
<% end %>
<% end %>
由于现在您在 ruby 而不是在 SQL 中完成所有工作,因此您不能再使用#order
订购东西(这会在您的 SQL 中添加一个子句作为查询,但我可以用#sort_by
来演示)示例的最内层循环。
虽然此代码会在大型数据库中导致显着的性能损失,但在小型测试应用程序中这将为您提供很好的服务。 While this will be slower than a SQL solution, it's general complexity is similar, as even in SQL you still have the problem that you'll be issuing CountryItem.where CountryItem.where(user:current_user).count
.count SQL queries which in and of itself is expensive .
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.