Crossing multiple arrays in Ruby

I have several arrays of subclass instances ActiveRecord Itemthat I need to execute through printing according to the earliest event. In this case, I need to print the payment and print service dates as follows:

Item Maintenance is required after 5 days
Payment is required for item B for 6 days
Item Payment is required for 7 days
Maintenance for item B for 8 days

Currently, I have two queries to search for elements maintenanceand payment(non-exclusive query) and to output them of the following type:

<%- item_p = nil -%>
<%- item_m = nil -%>

<%- loop do -%>
  <% item_p ||= @items_p.shift %>
  <% item_m ||= @items_m.shift %>

  <%- if item_p.nil? and item_m.nil? then break -%>
  <%- elsif item_p and (item_m.nil? or item_p.paymt < item_m.maint) then -%>
    <%= item_p.name %> payment required in ...
  <%- elsif item_m and (item_p.nil? or item_m.maint < item_p.paymt) then -%>
    <%= item_m.name %> maintenance required in ...
  <%- end -%>
<%- end -%>

Any way to clear the readability of the above (ugly) code?

+5
3

(.. ):

# In your controller:
@items = @items_p.map{ |item| {:item => item, :days => item.paymt, :description => "payment"} } 
@items += @items_m.map{ |item| {:item => item, :days => item.maint, :description => "maintenance"} }
@items = @items.sort_by{ |item| item[:day] }

# In your view:
<% @items.each do |item| %>
  <%= item[:item].name %> <%= item[:description] %> required in <%= item[:days] %> days
<% end %>
+2

, . , , .

, , Payment Maintenance:

module Due
  include Comparable

  # Compare this object with another. Used for sorting.
  def <=>(other)
    self.due <=> other.due
  end
end

class Payment < ActiveRecord::Base
  include Due

  alias_method :due, :payment

  def action
    "#{name} requires payment"
  end
end

class Maintenance < ActiveRecord::Base
  include Due

  alias_method :due, :maintenance

  def action
    "#{name} requires maintenance"
  end
end

, action, due <=> ? Ruby Comparable. :

# Assuming 'payment' and 'maintenance' are date fields...
a = Payment.new :payment => 3.days.from_now
b = Maintenance.new :maintenance => 2.days.from_now
[a, b].sort
#=> [b, a]

, :

<% (@payment_items + @maintenance_items).sort.each do |item| %>
  <%= item.action %> in <%= distance_of_time_in_words_to_now(item.due) %><br/>
<% end %>

, , , , .

+5

. , , .

:

length = [ @items_p.length, @items_m.length ].sort.last

@messages = [ ]

length.times do |i|
  item_p = @items_p[i]
  item_m = @items_m[i]

  if (item_p and (item_m and item_p.paymt < item_m.maint) or !item_m)
    @messages << "#{item_p.name} payment required in ..."
  elsif (item_m and (item_p and item_m.maint < item_p.paymt) or !item_p)
    @messages << "#{item_m.name} maintenance required in ..."
  end
end

@messages .

, . , , paymt maint . , , .

[ p, m ], :

items.each do |pair|
  first_due = pair.compact.sort_by(&:due).first
  @messages << "#{first_due.name} #{first_due.action} required in ..."
end

action payment maintenance .

+1
source

All Articles