Software Development (CSC 321 2015F) : Outlines

Outline 05: Ruby on Rails, Continued


Held: ,

Back to Outline 04 - Ruby on Rails & Software as a Service. On to Outline 06 - Behavior-Driven Development.

Summary

We continue our exploration of Rails by reviewing the latest assignment.

Related Pages

Overview

Administrivia

Sorting the List of Movies

Filtering the List of Movies

Remembering Settings (1)

This is the second half of filtering

Remembering Settings (2)

One Solution

Stolen from the SaaSbook folks.

app/models/movie.rb

class Movie < ActiveRecord::Base
  def self.all_ratings
    %w(G PG PG-13 NC-17 R)
  end
end

app/controllers/movies_controller

  def index
    sort = params[:sort] || session[:sort]
    case sort
    when 'title'
      ordering,@title_header = {:title => :asc}, 'hilite'
    when 'release_date'
      ordering,@date_header = {:release_date => :asc}, 'hilite'
    end
    @all_ratings = Movie.all_ratings
    @selected_ratings = params[:ratings] || session[:ratings] || {}

    if @selected_ratings == {}
      @selected_ratings = Hash[@all_ratings.map {|rating| [rating, rating]}]
    end

    if params[:sort] != session[:sort] or params[:ratings] != session[:ratings]
      session[:sort] = sort
      session[:ratings] = @selected_ratings
      redirect_to :sort => sort, :ratings => @selected_ratings and return
    end
    @movies = Movie.where(rating: @selected_ratings.keys).order(ordering)
  end

app/views/movies/index.html.haml

%h1 All Movies

= form_tag movies_path, :method => :get, :id => 'ratings_form' do
  = hidden_field_tag "title_sort", true if @title_header
  = hidden_field_tag ":release_date_sort", true if @date_header
  Include: 
  - @all_ratings.each do |rating|
    = rating
    = check_box_tag "ratings[#{rating}]", 1, @selected_ratings.include?(rating), :id => "ratings_#{rating}"
  = submit_tag 'Refresh', :id => 'ratings_submit'

%table#movies
  %thead
    %tr
      %th{:class => @title_header}= link_to 'Movie Title', movies_path(:sort => 'title', :ratings => @selected_ratings), :id => 'title_header'
      %th Rating
      %th{:class => @date_header}= link_to 'Release Date', movies_path(:sort => 'release_date', :ratings => @selected_ratings), :id => 'release_date_header'
      %th More Info
  %tbody
    - @movies.each do |movie|
      %tr
        %td= movie.title 
        %td= movie.rating
        %td= movie.release_date
        %td= link_to "More about #{movie.title}", movie_path(movie)

= link_to 'Add new movie', new_movie_path

Morals from the Assignment