From 28fbc518f39777ce50e907fa56cfbefe935e061e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sede=C3=B1o?= Date: Tue, 2 Feb 2016 00:16:43 +0100 Subject: [PATCH] Add registration_limit to conference model. Added the input for registration limit in the edit conference form. In the controller, if the limit has exceeded redirect to root_path with an alert. fix #761 --- .../admin/conference_controller.rb | 2 +- .../conference_registrations_controller.rb | 5 ++ app/models/conference.rb | 5 ++ app/models/registration.rb | 7 +++ app/views/admin/conference/edit.html.haml | 3 +- .../conference/_conference_details.html.haml | 4 +- app/views/conference/_registration.html.haml | 30 ++++++----- ...1_add_registration_limit_to_conferences.rb | 5 ++ db/schema.rb | 3 +- spec/factories/conferences.rb | 1 + spec/models/conference_spec.rb | 50 +++++++++++++++++++ spec/models/registration_spec.rb | 25 ++++++++++ 12 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 db/migrate/20160201221411_add_registration_limit_to_conferences.rb create mode 100644 spec/models/registration_spec.rb diff --git a/app/controllers/admin/conference_controller.rb b/app/controllers/admin/conference_controller.rb index 7ab374b9..4ef6b883 100644 --- a/app/controllers/admin/conference_controller.rb +++ b/app/controllers/admin/conference_controller.rb @@ -211,7 +211,7 @@ module Admin :vpositions_attributes, :use_volunteers, :color, :sponsorship_levels_attributes, :sponsors_attributes, :photos_attributes, :targets, :targets_attributes, - :campaigns, :campaigns_attributes) + :campaigns, :campaigns_attributes, :registration_limit) end def get_users(role_name) diff --git a/app/controllers/conference_registrations_controller.rb b/app/controllers/conference_registrations_controller.rb index 23e3cf1a..c9d7d216 100644 --- a/app/controllers/conference_registrations_controller.rb +++ b/app/controllers/conference_registrations_controller.rb @@ -20,6 +20,11 @@ class ConferenceRegistrationsController < ApplicationController redirect_to edit_conference_conference_registrations_path(@conference.short_title) end + if @conference.registration_limit_exceeded? + redirect_to root_path, alert: "Sorry, registration limit exceeded for #{@conference.title}" + return + end + @registration = Registration.new # @user variable needs to be set so that _sign_up_form_embedded works properly diff --git a/app/models/conference.rb b/app/models/conference.rb index 987f2ef8..5b595f5e 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -65,6 +65,7 @@ class Conference < ActiveRecord::Base validates_uniqueness_of :short_title validates_format_of :short_title, with: /\A[a-zA-Z0-9_-]*\z/ + validates :registration_limit, numericality: { only_integer: true, greater_than_or_equal_to: 0 } # This validation is needed since a conference with a start date greater than the end date is not possible validate :valid_date_range? @@ -536,6 +537,10 @@ class Conference < ActiveRecord::Base email_settings.conference_registration_dates_updated_body end + def registration_limit_exceeded? + registration_limit > 0 && registrations.count >= registration_limit + end + private after_create do diff --git a/app/models/registration.rb b/app/models/registration.rb index 1866c430..69af5402 100644 --- a/app/models/registration.rb +++ b/app/models/registration.rb @@ -26,6 +26,7 @@ class Registration < ActiveRecord::Base validates :user, presence: true validates_uniqueness_of :user_id, scope: :conference_id, message: 'already Registered!' + validate :registration_limit_not_exceed, on: :create after_create :set_week, :subscribe_to_conference, :send_registration_mail @@ -49,4 +50,10 @@ class Registration < ActiveRecord::Base self.week = created_at.strftime('%W') save! end + + def registration_limit_not_exceed + if self.conference.registration_limit>0 && self.conference.registrations(:reload).count >= self.conference.registration_limit + errors.add(:base, 'Registration limit exceeded') + end + end end diff --git a/app/views/admin/conference/edit.html.haml b/app/views/admin/conference/edit.html.haml index 5a931d1e..cbbfb3e7 100644 --- a/app/views/admin/conference/edit.html.haml +++ b/app/views/admin/conference/edit.html.haml @@ -18,5 +18,6 @@ = f.input :timezone, :as => :time_zone, :hint => "The conference time zone" = f.input :start_date, :as => :string, :input_html => { :id => "conference-start-datepicker", :readonly => "readonly" } = f.input :end_date, :as => :string, :input_html => { :id => "conference-end-datepicker", :readonly => "readonly" } + = f.inputs name: "Registrations" do + = f.input :registration_limit, as: :number, in: 0..9999, hint: "Limit the number of registrations to the conference (0 no limit)" = f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"} - diff --git a/app/views/conference/_conference_details.html.haml b/app/views/conference/_conference_details.html.haml index 165dc6f1..d3c07658 100644 --- a/app/views/conference/_conference_details.html.haml +++ b/app/views/conference/_conference_details.html.haml @@ -27,7 +27,9 @@ - if conference.user_registered?(current_user) = link_to "My Registration", conference_conference_registrations_path(conference.short_title), :class =>"btn btn-default" - else - = link_to "Register", new_conference_conference_registrations_path(conference.short_title), :class =>"btn btn-default" + = link_to "Register", new_conference_conference_registrations_path(conference.short_title), class: "btn btn-default", disabled: conference.registration_limit_exceeded? + - if conference.registration_limit_exceeded? + Sorry, no places left - if !current_user.nil? && current_user.proposal_count(conference) > 0 = link_to "My Proposals", conference_program_proposal_index_path(conference.short_title), :class =>"btn btn-default" - elsif conference.program.cfp_open? diff --git a/app/views/conference/_registration.html.haml b/app/views/conference/_registration.html.haml index aa0d29f8..b7540b81 100644 --- a/app/views/conference/_registration.html.haml +++ b/app/views/conference/_registration.html.haml @@ -6,19 +6,25 @@ .row .col-md-12.text-center %h1 Registration - - if @conference.tickets.empty? - %p.lead - Going to - = @conference.short_title - is free of charge. + + - if @conference.registration_limit_exceeded? %p - We only ask you to register yourself until - = @conference.registration_period.end_date.strftime('%A, %B %-d. %Y') - so we can plan for the right amount of people. + Sorry, the conference registration limit has exceeded - else - %p - The registration period ends on - = @conference.registration_period.end_date.strftime('%A, %B %-d. %Y') - %p.cta-button + - if @conference.tickets.empty? + %p.lead + Going to + = @conference.short_title + is free of charge. + %p + We only ask you to register yourself until + = @conference.registration_period.end_date.strftime('%A, %B %-d. %Y') + so we can plan for the right amount of people. + %p.cta-button + - else + %p + The registration period ends on + = @conference.registration_period.end_date.strftime('%A, %B %-d. %Y') + %p.cta-button = link_to(new_conference_conference_registrations_path(@conference.short_title), class: 'btn btn-lg btn-success') do Register Now diff --git a/db/migrate/20160201221411_add_registration_limit_to_conferences.rb b/db/migrate/20160201221411_add_registration_limit_to_conferences.rb new file mode 100644 index 00000000..bbc8724e --- /dev/null +++ b/db/migrate/20160201221411_add_registration_limit_to_conferences.rb @@ -0,0 +1,5 @@ +class AddRegistrationLimitToConferences < ActiveRecord::Migration + def change + add_column :conferences, :registration_limit, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 2eaf0334..85f41ae0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151031092713) do +ActiveRecord::Schema.define(version: 20160201221411) do create_table "ahoy_events", force: true do |t| t.uuid "visit_id" @@ -102,6 +102,7 @@ ActiveRecord::Schema.define(version: 20151031092713) do t.string "color" t.text "events_per_week" t.text "description" + t.integer "registration_limit", default: 0 end create_table "conferences_questions", id: false, force: true do |t| diff --git a/spec/factories/conferences.rb b/spec/factories/conferences.rb index b86dc58b..d39db79f 100644 --- a/spec/factories/conferences.rb +++ b/spec/factories/conferences.rb @@ -7,6 +7,7 @@ FactoryGirl.define do timezone 'Amsterdam' start_date { Date.today } end_date { 6.days.from_now } + registration_limit 0 factory :full_conference do splashpage diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index 54e679a1..ccf2c745 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -1479,6 +1479,48 @@ describe Conference do end end + describe 'registration_limit_exceeded?' do + context 'limit less than 0' do + before do + subject.registration_limit = -1 + end + it '#registration_limit_exceeded? is false' do + expect(subject.registration_limit_exceeded?).to be false + end + end + + context 'limit is 0' do + before do + subject.registration_limit = 0 + end + it '#registration_limit_exceeded? is false' do + expect(subject.registration_limit_exceeded?).to be false + end + end + + context 'limit is 1' do + before do + subject.registration_limit = 1 + end + context 'there are no registration' do + it '#registration_limit_exceeded? is false' do + expect(subject.registration_limit_exceeded?).to be false + end + end + + context 'there are 1 registration' do + before do + registration1 = create(:registration) + subject.registrations << registration1 + end + + it '#registration_limit_exceeded? is true' do + expect(subject.registration_limit_exceeded?).to be true + end + end + end + end + describe 'validations' do it 'has a valid factory' do @@ -1513,6 +1555,14 @@ describe Conference do should_not allow_value('&%§!?äÄüÜ/()').for(:short_title) end + it 'is not valid with a registration limit as float' do + should_not allow_value(0.5).for(:registration_limit) + end + + it 'is not valid with a negative registration limit' do + should_not allow_value(-1).for(:registration_limit) + end + describe 'valid_date_range?' do it 'is not valid if start date is greater than end date' do diff --git a/spec/models/registration_spec.rb b/spec/models/registration_spec.rb new file mode 100644 index 00000000..1bf9e88f --- /dev/null +++ b/spec/models/registration_spec.rb @@ -0,0 +1,25 @@ +#!/bin/env ruby +# encoding: utf-8 +require 'spec_helper' + +describe 'Registration' do + describe 'validations' do + it 'has a valid factory' do + expect(build(:registration)).to be_valid + end + + describe 'registration_limit_not_exceed' do + it 'is not valid when limit exceeded' do + conference = build(:conference) + conference.registration_limit = 1 + registration1 = build(:registration, conference: conference) + registration1.save + registration2 = build(:registration, conference: conference) + registration2.save + expect(conference.registrations.size).to be 1 + expect(registration2.valid?).to be false + expect(registration2.errors.full_messages).to eq(['Registration limit exceeded']) + end + end + end +end