Boguz
Boguz

Reputation: 1823

Order content on button click on Rails

I am doing a "Vinyl Record Collection" app using Rails. The goal is for me to learn how to use Ruby on Rails.

I have the main app working. I used rails g scaffold record artist:string title:string publisher:string tracks:text year:integer and everything is working fine. I have also styled it and now it is time to add some nice features... ;)

I would like to add a couple of buttons to order the Record List (index.html.erb) in different ways. One button to see if Alphabetically, on to see it by Record title, on to see it by year,...

But i really have no idea on how to go about it. I have tryed to search in google, but i am not even sure on what to look for. Is it the sort_by? Is it sort? Is it .order? Should i do it using Rails or using jQuery? =/

I think that i could sort something using sort, for instance to order by year:

@records.sort! { |a,b| a.year <=> b.year }

but how do i then display the changes? How do i make it work with a button click?

How do i make the view update according to the button clicked?

I would very much appreciate any hel you can give me.

Thank you! =)

Upvotes: 0

Views: 1969

Answers (2)

max
max

Reputation: 102045

Using .sort or .sort_by or any of the methods that come from Enumerable can be very poor for performance and lead to memory issues.

To sort in Ruby you need to first load all the records from the database and then load them into memory and then re-orders the array. This works fine when you're building a little toy app but for a an app with thousands of records this will quickly bring the server to its knees.

Instead you want to sort in the database by using .order

@newest = Record.order(year: :desc).limit(100)
# SELECT records.* FROM records ORDER BY year DESC LIMIT 100

To add filtering, sorting or search queries you want to use query parameters. You don't need to alter your existing routes as rails will add any query parameters from the request URL to the params hash.

class RecordsController
  # ...
  # GET /index
  # GET /index?order=[year, artist, title]
  def index
    @records = Record.all
    if params[:order].in? %w[year artist title]
      # adds ORDER to the scope
      @records.merge!( Record.order("? DESC", params[:order]) )
    end
  end
end

Should i do it using Rails or using jQuery?

I would recommend you start by learning how to build "classical" synchronous web apps in Rails. Thats enough in itself.

Revisit ajax once you understand the fundamentals.

To create links to sort the results you would do:

<p>Sort by: 
<%= link_to "Year", records_path(order: 'year') %>,
<%= link_to "Artist", records_path(order: 'artist') %>,
<%= link_to "Title", records_path(order: 'title') %>
</p>

Upvotes: 3

Boguz
Boguz

Reputation: 1823

i used a lot of the code @max wrote in is answer. Had to change it a little bit to make it work.

Ended up using the following code on my records_controller.rb

def index

    @records = Record.order(:artist)

    if params[:order] == 'artist'
        @records = Record.all.order('artist')
    elsif params[:order] == 'title'
        @records = Record.all.order('title')
    elsif params[:order] == 'year'
        @records = Record.all.order('year')
    else
        @Records = Record.all
    end 

end

maybe this can help someone else some day... ;)

Upvotes: 1

Related Questions