From 6ddacf8c87fdb059969787337c3f0f14009f7d8e Mon Sep 17 00:00:00 2001 From: dovadi Date: Mon, 31 Mar 2014 16:50:29 +0200 Subject: [PATCH] Now correct implementation of creating or updating a participation in case the participant is already known --- app/controllers/participants_controller.rb | 2 +- app/models/participant.rb | 55 +++++++++++++--------- test/fixtures/categories.yml | 8 ++++ test/models/participant_test.rb | 48 ++++++++++++------- 4 files changed, 75 insertions(+), 38 deletions(-) diff --git a/app/controllers/participants_controller.rb b/app/controllers/participants_controller.rb index 7deb3f6..b50e8e8 100644 --- a/app/controllers/participants_controller.rb +++ b/app/controllers/participants_controller.rb @@ -27,7 +27,7 @@ def create @participant = Participant.new(participant_params) respond_to do |format| - if @participant.save + if @participant.store format.html { redirect_to @participant, notice: t('activerecord.successful.messages.created', :model => @participant.class.model_name.human) } format.json { render action: 'show', status: :created, location: @participant } else diff --git a/app/models/participant.rb b/app/models/participant.rb index 63a3992..1777c53 100644 --- a/app/models/participant.rb +++ b/app/models/participant.rb @@ -2,51 +2,64 @@ class Participant < ActiveRecord::Base attr_accessor :activity_id, :distance - has_many :participations, dependent: :destroy + has_many :participations, dependent: :destroy - validates :firstname, :lastname, :street, :street_number, :zipcode, :city, :email, :phone, :date_of_birth, :gender, :distance, presence: true + validates :firstname, :lastname, :street, :street_number, :zipcode, :city, :email, :phone, :date_of_birth, :gender, :distance, presence: true - validates :email, format: /\A([^@\s]{1}+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, allow_blank: true + validates :email, format: /\A([^@\s]{1}+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, allow_blank: true - validates :gender, inclusion: {in: ['F', 'M']} + validates :gender, inclusion: {in: ['F', 'M']} - validates :zipcode, format: /\A[0-9]{4}[A-Z]{2}\z/ + validates :zipcode, format: /\A[0-9]{4}[A-Z]{2}\z/ - validates :phone, format: /\A[0-9]{10}\z/ + validates :phone, format: /\A[0-9]{10}\z/ - after_save :assign_participation_if_valid - before_create :prevent_double_participant + after_save :assign_participation_if_valid def attributes - super.merge('distance' => self.distance, 'activity_id' => self.activity_id) + super.merge('distance' => distance, 'activity_id' => activity_id) end def distance - current_participation.present? ? current_participation.distance : @distance + active_participation.present? ? active_participation.distance : @distance + end + + def store + participant = Participant.where(firstname: firstname, lastname: lastname, date_of_birth: date_of_birth).first + if participant.present? + @existing_participant = participant + assign_participation_if_valid + true + else + save + end end private - def current_participation + def current_id + self.id || (@existing_participant.present? && @existing_participant.id) + end + + def active_participation participations.where(activity_id: Activity.active.id).first end - def current_category - Category.find_matching(date_of_birth: self.date_of_birth, gender: self.gender, distance: @distance, activity_id: @activity_id) + def associated_participation + Participation.where(activity_id: activity_id, participant_id: current_id).first if current_id end - def prevent_double_participant - participant = Participant.where(firstname: firstname, lastname: lastname, date_of_birth: date_of_birth).first - participant.present? ? false : true + def associated_category + Category.find_matching(date_of_birth: date_of_birth, gender: gender, distance: distance, activity_id: activity_id) end def participation_fields_present? - @distance.present? && @activity_id.present? + distance.present? && activity_id.present? end def assign_participation_if_valid if participation_fields_present? - if current_category.present? + if associated_category.present? create_or_update_participation else self.errors[:base] = 'Geen bijbehorende categorie gevonden!' @@ -56,10 +69,10 @@ def assign_participation_if_valid end def create_or_update_participation - if current_participation.present? - current_participation.update_attribute(:category_id, current_category.id) + if associated_participation.present? + associated_participation.update_attribute(:category_id, associated_category.id) else - Participation.create!(participant_id: self.id, category_id: current_category.id, activity_id: @activity_id) + Participation.create!(participant_id: current_id, category_id: associated_category.id, activity_id: activity_id) end end diff --git a/test/fixtures/categories.yml b/test/fixtures/categories.yml index 8aa2c29..c6524d5 100644 --- a/test/fixtures/categories.yml +++ b/test/fixtures/categories.yml @@ -74,4 +74,12 @@ tenth: age_from: 18 age_to: 50 activity_id: 2 + gender: M + +eleventh: + description: Mannen senioren 8k + distance: 4 + age_from: 18 + age_to: 50 + activity_id: 3 gender: M \ No newline at end of file diff --git a/test/models/participant_test.rb b/test/models/participant_test.rb index 4a40239..3e6475a 100644 --- a/test/models/participant_test.rb +++ b/test/models/participant_test.rb @@ -39,13 +39,6 @@ @participant.attributes.keys.include?('activity_id').must_equal true end - it 'should not create a participant for the second time' do - participant = Participant.new(@attributes) - participant.save.must_equal true - participant = Participant.new(@attributes.merge(lastname: 'stam')) - participant.save.must_equal false - end - describe 'Participation' do before do @@ -57,19 +50,11 @@ Participation.count.must_equal 1 end - it 'should return the corresponding distance' do + it 'should return the corresponding distance assuming there is only one active activity' do participant = Participant.find(@participant.id) participant.distance.must_equal 8 end - it 'should be able to update the distance (i.e. category)' do - @participant.distance = 4 - @participant.save - participant = Participant.find(@participant.id) - participant.distance.must_equal 4 - end - - end describe 'In case no category found' do @@ -94,4 +79,35 @@ end + describe 'With an existing participant' do + + before do + Participation.destroy_all + Participant.destroy_all + @activity = activities(:active) + @participant = Participant.create(@attributes.merge(activity_id: @activity.id)) + end + + it 'should not create the participant for the second time' do + participant = Participant.new(@attributes.merge(lastname: 'stam', activity_id: @activity.id)) + participant.store.must_equal true + Participant.count.must_equal 1 + end + + it 'should not create a new participant but create a new participation in case of a new activity' do + participant = Participant.new(@attributes.merge(lastname: 'stam', distance: 4, activity_id: 3)) + participant.store.must_equal true + Participation.count.must_equal 2 + end + + it 'should not create a new participant but edit the corresponding participation in case of the same activity (i.e. a different category)' do + participant = Participant.new(@attributes.merge(lastname: 'stam', distance: 4, activity_id: @activity.id)) + participant.store.must_equal true + @participant.participations.first.distance.must_equal 4 + end + + end + + + end