1

I'm doing a flight-booking application in Rails and have successfully listed dates of flights as arrays.

However, I have a problem with duplicates. I've used a select_tag(:dates, options_for_select(@dates), which works, but I've got all these duplicate dates.

Heres the code for @dates.

@dates=Flight.all.map do |a|
  dates=[]
  unless dates.any? && dates.last[0]==a.flight_date_formatted
    dates<<[a.flight_date_formatted, a.id]
  end
end

This returns an array of arrays of the type of ["22/5/2016", 1]. I can't use unique because of the second element, in which the id is always different.

In the code I'm trying to access the last/first element of the array and get its [0] element, which would be "22/5/2016" and if it's equal to the current date then skip this iteration. Unfortunately it isn't working as I expect.

There are 7 flights and only 3 different Dates so it's not hard for it to catch at least one different.

How can I filter the duplicate records?

1 Answer 1

2

To query the flights directly from the database uniquely by date and already sorted, you can use ActiveRecord do this:

today = DateTime.now.to_date
@flights = Flight.select("DISTINCT flight_date, *").where("flight_date < ?", today).group(:flight_date).order("flight_date")

In this, the DISTINCT and group are used to make the flights unique by flight_date. The order is used to sort the results; if you wanted them sorted in reverse order, use order("flight_date DESC"). The where says to only retrieve the flights that have a flight date before today. Any of these can be changed to suit similar queries, as well.

If have already retrieved duplicates from the database, you can sort them in memory with the Ruby standard library Array#unique with a block. Try this:

@flights = Flight.all.unique {|a,b| a[0] <=> b[0] }

This will return an array that is unique by the first element.

To correct your filter code, you just need to return the dates value from the block. This should return the correct value from the map block:

@dates=Flight.all.map do |a|
  dates=[]
  unless dates.any? && dates.last[0]==a.flight_date_formatted
    dates<<[a.flight_date_formatted, a.id]
  end
  dates
end

The "short" way to filter out records is with Array#select, which you can use like this:

today = DateTime.now.strftime("%-d/%-m/%Y")
@flights = @flights.select {|flight| flight[0] != today }
Sign up to request clarification or add additional context in comments.

2 Comments

thank you, very elegant answer. I ended up using a helper method on the controller. Your way would be getting the flights with unique dates then running my dates code on top of it if I understood correctly.
@nathaks I updated my answer to include retrieving the records from the database already sorted and unique. This is actually better than doing this in memory. Regarding your comment question, these can be used together. They can also be used independently. It just depending on how you need it to work in your application. The database solution should sort and filter all at once. I updated the descriptions to be a little clearer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.