0

I have an array of objects containing three different models. Two of them have a common attribute of category, and a third one that we just added doesn't. I'm wanting to sort the array alphabetically using the category name for the first two and the object's name for the third. Since they are all strings, this seems possible, but I don't know how to make it work.

My controller:

def index
@opportunities = Opportunity.non_historical_active.order("title")
@recommendations = Recommendation.active
@fast_content = FastContent.where(:approved => true)
@skills = (@recommendations + @opportunities + @fast_content)

Array displayed in my view:

<% Array(@skills.sort_by{ |skill| skill.opportunity_category.name}).each_with_index do |opp, i| %>

This array worked before we added the @fast_content variable to @skills.

1 Answer 1

2

Assuming Opportunity and Recommendation should be sorted by opportunity_category.name and FastContent should be sorted by name, this would work:

@skills.sort_by { |skill|
  case skill
  when Opportunity, Recommendation
    skill.opportunity_category.name
  when FastContent
    skill.name
  end
}

Another option is to add a common method to all three classes:

class Opportunity < ActiveRecord::Base
  def sort_name
    opportunity_category.name
  end
end

class Recommendation < ActiveRecord::Base
  def sort_name
    opportunity_category.name
  end
end

class FastContent < ActiveRecord::Base
  def sort_name
    name
  end
end

And use that instead:

@skills.sort_by(&:sort_name)
Sign up to request clarification or add additional context in comments.

2 Comments

+1 for the second approach. That's what I'd do. Avoid type checking.
Agreed. The second approach did the trick perfectly. I had thought about the case statement method within the sort, but couldn't make it work in my head. Defining at the model level is much better for us. Thanks again.

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.