uniq
accepts a block. If a block is given, it will use the return value of the block for comparison.
Your code was close to the solution, but in your code the return value was only a_track[:composer]
which is the last evaluated statement.
You can join the attributes you want into a string and return that string.
new_tracks.uniq { |track| [track[:name], track[:artist], track[:composer]].join(":") }
A possible refactoring is
new_tracks.uniq { |track| track.attributes.slice('name', 'artist', 'composer').values.join(":") }
Or add a custom method in your model that performs the join, and call it
class Track < ActiveRecord::Base
def digest
attributes.slice('name', 'artist', 'composer').values.join(":")
end
end
new_tracks.uniq(&:digest)