Rails从视图条件中删除重复记录

时间:2016-04-29 21:25:17

标签: ruby-on-rails ruby

我有一个书籍视图,客户可以访问他们最新的产品。我正在尝试展示当前的产品和过期的产品。所有这一切都很好,除了重复的订单 - 我想消除欺骗。

e.g。如果当前图书标题与过期标题具有相同的标题,则不显示过期标题,如果过期订单与过期标题具有相同标题,则仅显示一个标题。

这是我的图书索引。

      <% if current_user_subscribed? %>
        <% @current_user.orders.map do |order| %>
          <% order.product.books.map do |book| %>   
            <% if order.created_at + order.expires.minutes > Time.now %>
              <%= link_to book.title, book %>

          # show book.title without dupes
            <% elsif order.product_id != order.product_id %> 
              <%= link_to book.title, book %>
            <% end %>
          <% end %>
        <% end %>

1 个答案:

答案 0 :(得分:1)

听起来像模特关注的问题,而不是视角问题。

# Model
class Book < ActiveRecord::Base
  # Class methods are allowed to be chained on ActiveRecord::Relation returned by order.books
  # @return [Array<Book>]
  def self.without_dups
    group_by(&:title).map do |title, books| 
      # Here I assume you simply want one book per title, with preference for the non-expired ones
      books.sort_by {|book| book.is_expired ? 0 : 1}.first
    end
  end
end

# Controller
class BooksController < ApplicationController
  def index
    # includes is used to avoid N+1 queries
    @orders = current_user.orders.includes(:books)
  end
end

# View
<% @orders.each do |order| %>
  <% order.books.without_dups.each do |book| %>
    ...
  <% end %>
<% end %>

其他想法

您的原始视图代码包含许多逻辑。它通过直接在@current_user上调用方法来自行决定呈现什么。如果视图侧重于如何呈现,同时保留要呈现给控制器的内容,则效果会更好。这就是我的控制器设置@orders并从那里开始视图的原因。此外,调用#map是不必要的。您不依赖于返回值。它没有害处,但#each在这种情况下更自然。