Skip to content

Instantly share code, notes, and snippets.

@sipple
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save sipple/c388e163a27fb7c8f0f9 to your computer and use it in GitHub Desktop.

Select an option

Save sipple/c388e163a27fb7c8f0f9 to your computer and use it in GitHub Desktop.

Revisions

  1. sipple revised this gist Jun 7, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.rb
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    ##################
    # This code sample contains the logic for a page used by arts festival attendees to filter
    # the festival's events and find a show they're interested in seeing.
    # You can see the event list in action here: http://pghkids.org/events?sort=start_date
    # You can see the event list in action here: http://pghkids.org/events
    ##################

    ##################
  2. sipple revised this gist Jun 7, 2015. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions gistfile1.rb
    Original file line number Diff line number Diff line change
    @@ -8,6 +8,7 @@
    # FestivityEventsController, which receives a request with search criteria and returns
    # a list of matching events to the view.
    ##################

    class FestivityEventsController < ApplicationController
    include Festivity::Mixins::NotFound
    no_login_required
    @@ -165,6 +166,7 @@ def initialize(event_id, performances)
    ##################
    # Event List view, demonstrating how matched events are displayed in the browser
    ##################

    #event-list-items
    - @events.each do |event|
    .row.event-list-item{class: event.id, data:{ genre: event.categories.first.id, date: event.performances.first.start_date, location: event.locations.first.id} }
  3. sipple revised this gist Jun 7, 2015. 1 changed file with 12 additions and 4 deletions.
    16 changes: 12 additions & 4 deletions gistfile1.rb
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,13 @@
    ##################
    # This code sample contains the logic for a page used by arts festival attendees to filter
    # the festival's events and find a show they're interested in seeing.
    # You can see the event list in action here: http://pghkids.org/events?sort=start_date
    ##################



    ##################
    # FestivityEventsController, which receives a request with search criteria and returns
    # a list of matching events to the view.
    ##################
    class FestivityEventsController < ApplicationController
    include Festivity::Mixins::NotFound
    no_login_required
    @@ -35,7 +37,9 @@ def index
    end
    end

    ##################
    # FestivityEventList model, used to collect all matching events
    ##################

    class FestivityEventList

    @@ -103,8 +107,9 @@ def self.date_criteria(dates_string)
    end



    ##################
    # FestivityEventPerformance model, tied to a database view which collects event performance data
    ##################

    class FestivityEventList::FestivityEventPerformance < ActiveRecord::Base
    self.table_name = 'festivity_event_performances'
    @@ -117,7 +122,9 @@ class FestivityEventList::FestivityEventPerformance < ActiveRecord::Base

    end

    ##################
    # FestivityEvent model representing events which matched the search criteria and wrapping matching performances
    ##################

    class FestivityEventList::FestivityEvent
    include Festivity::Admin::AssetsHelper
    @@ -155,8 +162,9 @@ def initialize(event_id, performances)

    end

    ##################
    # Event List view, demonstrating how matched events are displayed in the browser

    ##################
    #event-list-items
    - @events.each do |event|
    .row.event-list-item{class: event.id, data:{ genre: event.categories.first.id, date: event.performances.first.start_date, location: event.locations.first.id} }
  4. sipple revised this gist Jun 7, 2015. 1 changed file with 21 additions and 26 deletions.
    47 changes: 21 additions & 26 deletions gistfile1.rb
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,8 @@
    # the festival's events and find a show they're interested in seeing.
    # You can see the event list in action here: http://pghkids.org/events?sort=start_date



    # FestivityEventsController, which receives a request with search criteria and returns
    # a list of matching events to the view.
    class FestivityEventsController < ApplicationController
    @@ -46,10 +48,10 @@ def initialize(event_performances)
    end

    def self.search(criteria, order_by)
    # Build the SQL where clause from the supplied criteria
    where_clause = parse_criteria(criteria)

    # Search the FestivityEventPerformance view for performances matching supplied criteria
    # and create a new FestivityEventList object with the results
    # Search the FestivityEventPerformance view and build a new FestivityEventList object with the results
    FestivityEventList.new(
    FestivityEventList::FestivityEventPerformance.
    includes(:assets).
    @@ -63,6 +65,20 @@ def self.search(criteria, order_by)

    private

    # The order of querying, depending on what is passed:
    # - If dates are passed, we search both start and end date between midnight and 11:59pm of that date.
    # That query returns any matching event ids.
    # - The event ids returned, if any, are added to the where clause for the next query
    # - Any category ids passed are added to the where clause as well.
    def self.parse_criteria(criteria)
    where_clause = {}
    event_ids = event_ids_for_dates(criteria[:dates]) if criteria[:dates]
    where_clause["site_id"] = Page.current_site.id
    where_clause["event_id"] = event_ids if event_ids
    where_clause["festivity_categories.id"] = criteria[:categories].split(",") if criteria[:categories]
    where_clause
    end

    # Return a list of unique event ids that match the provided dates
    def self.event_ids_for_dates(dates)
    FestivityEventList::FestivityEventPerformance.where(date_criteria(dates)).map {|e| e.event_id}.uniq
    @@ -84,22 +100,10 @@ def self.date_criteria(dates_string)
    end
    date_queries.join(" OR ")
    end

    # The order of querying, depending on what is passed:
    # - If dates are passed, we search both start and end date between midnight and 11:59pm of that date.
    # That query returns any matching event ids.
    # - The event ids returned, if any, are added to the where clause for the next query
    # - Any category ids passed are added to the where clause as well.
    def self.parse_criteria(criteria)
    where_clause = {}
    event_ids = event_ids_for_dates(criteria[:dates]) if criteria[:dates]
    where_clause["site_id"] = Page.current_site.id
    where_clause["event_id"] = event_ids if event_ids
    where_clause["festivity_categories.id"] = criteria[:categories].split(",") if criteria[:categories]
    where_clause
    end
    end



    # FestivityEventPerformance model, tied to a database view which collects event performance data

    class FestivityEventList::FestivityEventPerformance < ActiveRecord::Base
    @@ -124,6 +128,7 @@ class FestivityEventList::FestivityEvent
    def initialize(event_id, performances)
    @id = event_id
    @performances = performances
    # For event-level information, like title, just use the first event performance
    @title = performances.first.event_title
    @short_description = performances.first.short_description
    @header = performances.first.header
    @@ -148,11 +153,6 @@ def initialize(event_id, performances)

    end

    def image
    image = assets.select { |asset| asset.title == "featured_image" }.first if assets.size > 0
    image.thumbnail(:normal) unless image.nil?
    end

    end

    # Event List view, demonstrating how matched events are displayed in the browser
    @@ -204,17 +204,12 @@ def image
    %hr
    %p
    .event-list-item__info_short_description
    -# category = event.categories.first
    -# %a.strong(href='#')
    = category.name
    %span
    = event.short_description.html_safe
    %p
    .event-list-item__button-group
    = link_to "Details", event_path(event.id), class: 'btn event-list-item__btn'
    - unless event.buy_url.blank?
    = link_to "Tickets", "#{event.buy_url}", class: 'btn event-list-item__btn', target: '_blank'
    -#%button.btn.event-list-item__btn{href: "", data: {toggle:"modal", target:"#share-modal"}, type: "button"}
    Share
    - unless event.locations.first.directions_url.blank?
    = link_to "Directions", "#{event.locations.first.directions_url}", class: 'btn event-list-item__btn', target: '_blank'
  5. sipple revised this gist Jun 7, 2015. 1 changed file with 15 additions and 6 deletions.
    21 changes: 15 additions & 6 deletions gistfile1.rb
    Original file line number Diff line number Diff line change
    @@ -1,22 +1,29 @@
    # This code sample contains the logic for a page used by arts festival attendees to filter
    # the festival's events and find a show they're interested in seeing.
    # You can see the event list in action here: http://pghkids.org/events?sort=start_date

    # FestivityEventsController, which receives a request with search criteria and returns
    # a list of matching events to the view.
    class FestivityEventsController < ApplicationController
    include Festivity::Mixins::NotFound
    no_login_required
    trusty_layout 'base'

    # Event search requests are cached; because some requests are for the full page and some are AJAX
    # caching separates requests by format.
    caches_action :index, cache_path: proc { |c| c.params.except(:_).merge(format: request.xhr?)}
    caches_action :show

    def index
    # Default sort is by event start date
    order_by = params[:sort] ? params[:sort] : "start_date"
    @title = "#{current_site.festivity_festival_name}: Events"

    # Pass search criteria to the FestivityEventList model to find relevant events
    @events = FestivityEventList.search(
    {dates: search_dates.join(","),
    categories: params[:categories]},
    order_by).events

    @selected_dates = params[:dates] ? params[:dates].split(",") : []
    @selected_categories = params[:categories] ? params[:categories].split(",") : []
    @selected_sort = order_by

    # If the request is AJAX, only return the event list itself, not the full page
    if request.xhr?
    render partial: "event_list"
    @@ -40,7 +47,9 @@ def initialize(event_performances)

    def self.search(criteria, order_by)
    where_clause = parse_criteria(criteria)
    # where in event ids

    # Search the FestivityEventPerformance view for performances matching supplied criteria
    # and create a new FestivityEventList object with the results
    FestivityEventList.new(
    FestivityEventList::FestivityEventPerformance.
    includes(:assets).
  6. sipple created this gist Jun 7, 2015.
    211 changes: 211 additions & 0 deletions gistfile1.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,211 @@
    class FestivityEventsController < ApplicationController
    include Festivity::Mixins::NotFound
    no_login_required
    trusty_layout 'base'

    caches_action :index, cache_path: proc { |c| c.params.except(:_).merge(format: request.xhr?)}
    caches_action :show

    def index
    order_by = params[:sort] ? params[:sort] : "start_date"
    @title = "#{current_site.festivity_festival_name}: Events"
    @events = FestivityEventList.search(
    {dates: search_dates.join(","),
    categories: params[:categories]},
    order_by).events

    @selected_dates = params[:dates] ? params[:dates].split(",") : []
    @selected_categories = params[:categories] ? params[:categories].split(",") : []
    @selected_sort = order_by
    # If the request is AJAX, only return the event list itself, not the full page
    if request.xhr?
    render partial: "event_list"
    else
    render 'index'
    end
    end
    end

    # FestivityEventList model, used to collect all matching events

    class FestivityEventList

    attr_reader :events

    def initialize(event_performances)
    @events = event_performances.group_by {|perf| perf.event_id }.
    map { |perfs| FestivityEventList::FestivityEvent.new(perfs[0], perfs[1]) }

    end

    def self.search(criteria, order_by)
    where_clause = parse_criteria(criteria)
    # where in event ids
    FestivityEventList.new(
    FestivityEventList::FestivityEventPerformance.
    includes(:assets).
    joins(:festivity_categories).
    where(where_clause).
    group("performance_id").
    order("featured_item DESC, #{order_by} ASC").
    preload(:festivity_categories)
    )
    end

    private

    # Return a list of unique event ids that match the provided dates
    def self.event_ids_for_dates(dates)
    FestivityEventList::FestivityEventPerformance.where(date_criteria(dates)).map {|e| e.event_id}.uniq
    end

    # Create a condition for start and end date between midnight and 11:59pm
    # for each date passed in and return the SQL condition
    def self.date_criteria(dates_string)
    date_queries = dates_string.split(',').map do |date_string|
    start_date = DateTime.parse(date_string)
    end_date = start_date.advance(hours: 23, minutes: 59)
    <<-SQL
    (
    (start_date >= '#{start_date}' AND start_date <= '#{end_date}')
    OR
    (end_date >= '#{start_date}' AND end_date <= '#{end_date}')
    )
    SQL
    end
    date_queries.join(" OR ")
    end

    # The order of querying, depending on what is passed:
    # - If dates are passed, we search both start and end date between midnight and 11:59pm of that date.
    # That query returns any matching event ids.
    # - The event ids returned, if any, are added to the where clause for the next query
    # - Any category ids passed are added to the where clause as well.
    def self.parse_criteria(criteria)
    where_clause = {}
    event_ids = event_ids_for_dates(criteria[:dates]) if criteria[:dates]
    where_clause["site_id"] = Page.current_site.id
    where_clause["event_id"] = event_ids if event_ids
    where_clause["festivity_categories.id"] = criteria[:categories].split(",") if criteria[:categories]
    where_clause
    end
    end

    # FestivityEventPerformance model, tied to a database view which collects event performance data

    class FestivityEventList::FestivityEventPerformance < ActiveRecord::Base
    self.table_name = 'festivity_event_performances'
    after_initialize :readonly!

    has_many :festivity_page_categories, foreign_key: :page_id, primary_key: :event_id
    has_many :festivity_categories, through: :festivity_page_categories
    has_many :page_attachments, primary_key: :event_id, foreign_key: :page_id
    has_many :assets, through: :page_attachments

    end

    # FestivityEvent model representing events which matched the search criteria and wrapping matching performances

    class FestivityEventList::FestivityEvent
    include Festivity::Admin::AssetsHelper

    attr_reader :id, :performances, :locations, :categories, :title, :short_description,
    :assets, :header, :sub_header, :featured_item, :buy_url

    def initialize(event_id, performances)
    @id = event_id
    @performances = performances
    @title = performances.first.event_title
    @short_description = performances.first.short_description
    @header = performances.first.header
    @sub_header = performances.first.sub_header
    @featured_item = performances.first.featured_item
    @buy_url = performances.first.buy_url

    @locations = self.performances.
    map{ |performance| FestivityEventList::FestivityLocation.new ({
    id: performance.location_id,
    slug: performance.location_slug,
    title: performance.location_title,
    directions_url: performance.festivity_directions_url,
    area_id: performance.area_id,
    area_slug: performance.area_slug,
    area_title: performance.area_title}) }.
    uniq{ |location| location.id }

    @categories = performances.first.festivity_categories

    @assets = performances.first.assets

    end

    def image
    image = assets.select { |asset| asset.title == "featured_image" }.first if assets.size > 0
    image.thumbnail(:normal) unless image.nil?
    end

    end

    # Event List view, demonstrating how matched events are displayed in the browser

    #event-list-items
    - @events.each do |event|
    .row.event-list-item{class: event.id, data:{ genre: event.categories.first.id, date: event.performances.first.start_date, location: event.locations.first.id} }
    %hr
    .event-list-item__photo.col-xs-12.col-sm-4
    .photo
    = link_to event_path(event.id) do
    %img.img-responsive{ src: "#{event.image}"}
    - if event.featured_item
    .event_list-item__photo-featured-item
    Featured Event!
    .event-list-item__info.col-xs-12.col-sm-8
    = link_to event_path(event.id) do
    %h2
    = event.title
    %h3
    %span.strong
    = event.header
    %span.light
    = event.sub_header
    %hr
    %p
    - if event.locations.count == 1
    - event_location = event.locations.first
    =link_to location_path(id: event_location.slug) do
    = event_location.title
    @
    =link_to area_path(id: event_location.area_slug) do
    = event_location.area_title
    - else
    Multiple Locations
    - if event.performances.count > 1
    %p
    Multiple dates and times&nbsp;
    %button.btn.btn-sm.btn-default.btn-popover{type: "button", data: {content: date_time_popover(event.performances), html: "true", placement:"top", toggle: "popover"}, title:"All Dates and Times"}
    Show all
    - else
    - event.performances.each do |perf|
    %p
    = perf.start_date.strftime("%A, %B %d")
    = ", "
    = perf.start_date.strftime("%I:%M%p").downcase
    = " - "
    = perf.end_date.strftime('%I:%M%p').downcase
    %hr
    %p
    .event-list-item__info_short_description
    -# category = event.categories.first
    -# %a.strong(href='#')
    = category.name
    %span
    = event.short_description.html_safe
    %p
    .event-list-item__button-group
    = link_to "Details", event_path(event.id), class: 'btn event-list-item__btn'
    - unless event.buy_url.blank?
    = link_to "Tickets", "#{event.buy_url}", class: 'btn event-list-item__btn', target: '_blank'
    -#%button.btn.event-list-item__btn{href: "", data: {toggle:"modal", target:"#share-modal"}, type: "button"}
    Share
    - unless event.locations.first.directions_url.blank?
    = link_to "Directions", "#{event.locations.first.directions_url}", class: 'btn event-list-item__btn', target: '_blank'