diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e7e50f4a..487a9fdb 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -317,6 +317,8 @@ Metrics/BlockLength: # Offense count: 23 Metrics/CyclomaticComplexity: Max: 12 + Exclude: + - 'app/models/track.rb' # Offense count: 2353 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. @@ -339,6 +341,8 @@ Metrics/ModuleLength: # Offense count: 15 Metrics/PerceivedComplexity: Max: 16 + Exclude: + - 'app/models/track.rb' # Offense count: 20 Style/AccessorMethodName: diff --git a/app/controllers/admin/tracks_controller.rb b/app/controllers/admin/tracks_controller.rb index c229b9b8..0eed1b2d 100644 --- a/app/controllers/admin/tracks_controller.rb +++ b/app/controllers/admin/tracks_controller.rb @@ -62,7 +62,7 @@ module Admin private def track_params - params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active) + params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active, :start_date, :end_date, :room_id) end end end diff --git a/app/models/room.rb b/app/models/room.rb index f8150f78..8a50551d 100644 --- a/app/models/room.rb +++ b/app/models/room.rb @@ -2,6 +2,7 @@ class Room < ActiveRecord::Base include RevisionCount belongs_to :venue has_many :event_schedules, dependent: :destroy + has_many :tracks has_paper_trail ignore: [:guid], meta: { conference_id: :conference_id } diff --git a/app/models/track.rb b/app/models/track.rb index 6228ff02..f29babde 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -6,6 +6,7 @@ class Track < ActiveRecord::Base belongs_to :program belongs_to :submitter, class_name: 'User' + belongs_to :room has_many :events, dependent: :nullify has_paper_trail only: [:name, :description, :color], meta: { conference_id: :conference_id } @@ -24,6 +25,10 @@ class Track < ActiveRecord::Base inclusion: { in: %w(new to_accept accepted confirmed to_reject rejected canceled withdrawn) }, if: :self_organized? validates :cfp_active, inclusion: { in: [true, false] }, if: :self_organized? + validates :start_date, presence: true, if: :accepted_or_confirmed? + validates :end_date, presence: true, if: :accepted_or_confirmed? + validates :room, presence: true, if: :accepted_or_confirmed? + validate :valid_dates, if: :accepted_or_confirmed? before_validation :capitalize_color @@ -105,6 +110,33 @@ class Track < ActiveRecord::Base end end + ## + # Checks if the track is accepted + # ====Returns + # * +true+ -> If the track's state is 'accepted' + # * +false+ -> If the track's state isn't 'accepted' + def accepted? + state == 'accepted' + end + + ## + # Checks if the track is confirmed + # ====Returns + # * +true+ -> If the track's state is 'confirmed' + # * +false+ -> If the track's state isn't 'confirmed' + def confirmed? + state == 'confirmed' + end + + ## + # Checks if the track is accepted or confirmed + # ====Returns + # * +true+ -> If the track's state is 'accepted' or 'confirmed' + # * +false+ -> If the track's state is neither 'accepted' nor 'confirmed' + def accepted_or_confirmed? + accepted? || confirmed? + end + private def generate_guid @@ -128,4 +160,28 @@ class Track < ActiveRecord::Base def create_organizer_role Role.where(name: 'track_organizer', resource: self).first_or_create(description: 'For the organizers of the Track') end + + def valid_dates + return unless start_date && end_date + + if program && program.conference && program.conference.start_date && (start_date < program.conference.start_date) + errors.add(:start_date, "can't be before the conference start date (#{program.conference.end_date})") + end + + if program && program.conference && program.conference.start_date && (end_date < program.conference.start_date) + errors.add(:end_date, "can't be before the conference start date (#{program.conference.end_date})") + end + + if program && program.conference && program.conference.end_date && (start_date > program.conference.end_date) + errors.add(:start_date, "can't be after the conference end date (#{program.conference.end_date})") + end + + if program && program.conference && program.conference.end_date && (end_date > program.conference.end_date) + errors.add(:end_date, "can't be after the conference end date (#{program.conference.end_date})") + end + + if start_date > end_date + errors.add(:start_date, 'can\'t be after the end_date') + end + end end diff --git a/app/views/admin/tracks/_form.html.haml b/app/views/admin/tracks/_form.html.haml index fe7f014a..cb2e8b01 100644 --- a/app/views/admin/tracks/_form.html.haml +++ b/app/views/admin/tracks/_form.html.haml @@ -8,10 +8,16 @@ Track .row .col-md-12 - = semantic_form_for(@track, url: (@track.new_record? ? admin_conference_program_tracks_path : admin_conference_program_track_path(@conference.short_title, @track))) do |f| + = semantic_form_for(@track, url: (@track.new_record? ? admin_conference_program_tracks_path(@conference.short_title) : admin_conference_program_track_path(@conference.short_title, @track))) do |f| = f.input :name = f.input :short_name, hint: "A short and unique handle for the track, using only letters, numbers, underscores, and dashes. This will be used to identify the track in URLs etc. Example: 'my_awesome_track'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' } = f.input :color, input_html: {size: 6, type: 'color'}, required: true + = f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? } + = f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? } + - if @conference.venue + = f.input :room, as: :select, collection: (@conference.venue.rooms).map {|room| ["#{room.name}", room.id]}, include_blank: true, label: 'Room', input_html: { class: 'select-help-toggle', required: @track.self_organized_and_accepted_or_confirmed? } + - else + Please add a venue with rooms, if you want to select a room for the track. = f.input :description, input_html: {rows: 2, data: { provide: 'markdown-editable' } }, hint: markdown_hint - if @track.self_organized? = f.input :cfp_active, label: 'Allow event submitters to select this track for their proposal' diff --git a/app/views/admin/tracks/index.html.haml b/app/views/admin/tracks/index.html.haml index 1cda360a..82167bb8 100644 --- a/app/views/admin/tracks/index.html.haml +++ b/app/views/admin/tracks/index.html.haml @@ -15,6 +15,9 @@ %th Color %th State %th Included in the Cfp + %th Room + %th Start Date + %th End Date %th Actions %tbody - @tracks.each do |track| @@ -52,6 +55,21 @@ off_text: 'No' } - else %i.fa.fa-check + %td + - if track.room + = link_to track.room.name, admin_conference_venue_room_path(@conference.short_title, track.room.id) + - else + N/A + %td + - if track.start_date + = track.start_date.strftime('%A, %B %-d. %Y') + - else + N/A + %td + - if track.end_date + = track.end_date.strftime('%A, %B %-d. %Y') + - else + N/A %td .btn-group{role: "group"} = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track), diff --git a/db/migrate/20170712120556_add_room_and_dates_to_tracks.rb b/db/migrate/20170712120556_add_room_and_dates_to_tracks.rb new file mode 100644 index 00000000..fb8a064b --- /dev/null +++ b/db/migrate/20170712120556_add_room_and_dates_to_tracks.rb @@ -0,0 +1,7 @@ +class AddRoomAndDatesToTracks < ActiveRecord::Migration + def change + add_reference :tracks, :room, index: true, foreign_key: true + add_column :tracks, :start_date, :date + add_column :tracks, :end_date, :date + end +end diff --git a/db/schema.rb b/db/schema.rb index ce680725..d3e14687 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -522,8 +522,12 @@ ActiveRecord::Schema.define(version: 20170807092805) do t.string "state" t.boolean "cfp_active" t.integer "submitter_id" + t.integer "room_id" + t.date "start_date" + t.date "end_date" end + add_index "tracks", ["room_id"], name: "index_tracks_on_room_id" add_index "tracks", ["submitter_id"], name: "index_tracks_on_submitter_id" create_table "users", force: :cascade do |t| diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb index 469fb117..f135f91d 100644 --- a/spec/models/room_spec.rb +++ b/spec/models/room_spec.rb @@ -12,6 +12,7 @@ describe Room do describe 'association' do it { should belong_to(:venue) } it { should have_many(:event_schedules).dependent(:destroy) } + it { should have_many(:tracks) } end describe 'callback' do