title: How to sort Ruby table by column headers?
body: <p>I'm creating a To Do List App using Ruby on Rails and I wanted to know how I would go about sorting the information on the table by the headers that I have? Like i'd like to be able to click on <strong>"Title"</strong> <strong>"Client"</strong> or <strong>"Done"</strong> and it sort them ASC or DESC. Also a way to get them back in their original order if possible. T</p>
  
  <p>Here is the code I'm trying:</p>
  
  <p><strong>projects_controller.rb:</strong></p>
  
  <pre><code>class ProjectsController &lt; ApplicationController
  
    before_action :set_project, only: [:show, :edit, :update, :destroy]
    helper_method :sort_column, :sort_direction
  
    def index
      @projects = Project.order(sort_column + " " + sort_direction)
    end
  
    private
  
    def sort_column
      Project.column_names.include?(params[:sort]) ? params[:sort] : "title"
    end
  
    def sort_direction
      %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
    end
  
  
    # GET /projects
    # GET /projects.json
    def index
      @projects = Project.all
    end
  
    # GET /projects/1
    # GET /projects/1.json
    def show
    end
  
    # GET /projects/new
    def new
      @project = Project.new
    end
  
    # GET /projects/1/edit
    def edit
    end
  
    # POST /projects
    # POST /projects.json
    def create
      @project = Project.new(project_params)
  
      respond_to do |format|
        if @project.save
          format.html { redirect_to @project, notice: 'Project was successfully created.' }
          format.json { render :show, status: :created, location: @project }
        else
          format.html { render :new }
          format.json { render json: @project.errors, status: :unprocessable_entity }
        end
      end
    end
  
    # PATCH/PUT /projects/1
    # PATCH/PUT /projects/1.json
    def update
      respond_to do |format|
        if @project.update(project_params)
          format.html { redirect_to @project, notice: 'Project was successfully updated.' }
          format.json { render :show, status: :ok, location: @project }
        else
          format.html { render :edit }
          format.json { render json: @project.errors, status: :unprocessable_entity }
        end
      end
    end
  
    # DELETE /projects/1
    # DELETE /projects/1.json
    def destroy
      @project.destroy
      respond_to do |format|
        format.html { redirect_to projects_url, notice: 'Project was successfully destroyed.' }
        format.json { head :no_content }
      end
    end
  
    private
      # Use callbacks to share common setup or constraints between actions.
      def set_project
        @project = Project.find(params[:id])
      end
  
      # Never trust parameters from the scary internet, only allow the white list through.
      def project_params
        params.require(:project).permit(:title, :description, :hours, :payrate, :done, :client)
      end
  
  
  
  end
  </code></pre>
  
  <p><strong>application_helper.rb:</strong></p>
  
  <pre><code>module ApplicationHelper
      def sortable(column, title = nil)
        title ||= column.titleize
        css_class = column == sort_column ? "current #{sort_direction}" : nil
        direction = column == sort_column &amp;&amp; sort_direction == "asc" ? "desc" : "asc"
        link_to title, {:sort =&gt; column, :direction =&gt; direction}, {:class =&gt; css_class}
      end
  end
  </code></pre>
  
  <p><strong>index.html.erb:</strong></p>
  
  <pre><code>&lt;h1 id="title"&gt;Project List&lt;/h1&gt;
  
  
  
    &lt;table&gt;
      &lt;thead&gt;
        &lt;tr id="headers"&gt;
          &lt;th&gt;&lt;%= sortable "title" %&gt;&lt;/th&gt;
          &lt;th&gt;&lt;%= sortable "client" %&gt;&lt;/th&gt;
          &lt;th&gt;Description&lt;/th&gt;
          &lt;th&gt;Hours&lt;/th&gt;
          &lt;th&gt;&lt;%= sortable "done" %&gt;&lt;/th&gt;
          &lt;th colspan="3"&gt;&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
  
  
      &lt;tbody class="col-md-2" id="listItems"&gt;
        &lt;% @projects.each do |project| %&gt;
          &lt;tr id="table"&gt;
            &lt;td&gt;&lt;%= project.title %&gt;&lt;/td&gt;
            &lt;td&gt;&lt;%= project.client %&gt;&lt;/td&gt;
            &lt;td &gt;&lt;%= project.description %&gt;&lt;/td&gt;
            &lt;td&gt;&lt;%= project.hours %&gt;&lt;/td&gt;
            &lt;td&gt;&lt;%= check_box_tag "project_#{project.id}", "#{project.done}", project.done?, disabled: "#{project.done?}" %&gt;
            &lt;/td&gt;
  
  
  
            &lt;td&gt;
              &lt;span title="Show"&gt;
                &lt;%= link_to " #{image_tag('show.png')}".html_safe, project, id:'showButton' %&gt;
              &lt;/span&gt;
            &lt;/td&gt;
  
  
            &lt;td&gt;
              &lt;span title="Edit"&gt;
                &lt;%= link_to " #{image_tag('edit.png')}".html_safe, edit_project_path(project), id:'editButton' %&gt;
              &lt;/span&gt;
            &lt;/td&gt;
  
            &lt;td&gt;
              &lt;span title="Delete"&gt;
                &lt;%= link_to " #{image_tag('destroy.png')}".html_safe, project, id:'destroyButton', method: :delete, data: { confirm: 'Are you sure?' } %&gt;
              &lt;/span&gt;
            &lt;/td&gt;
  
          &lt;/tr&gt;
        &lt;% end %&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  
    &lt;br&gt;
  
    &lt;%= link_to 'New Project', new_project_path, id:"new" %&gt;
  </code></pre>