Skip to content

Commit

Permalink
Now correct implementation of creating or updating a participation in…
Browse files Browse the repository at this point in the history
… case the participant is already known
  • Loading branch information
dovadi committed Mar 31, 2014
1 parent 2415ea8 commit 6ddacf8
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 38 deletions.
2 changes: 1 addition & 1 deletion app/controllers/participants_controller.rb
Expand Up @@ -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
Expand Down
55 changes: 34 additions & 21 deletions app/models/participant.rb
Expand Up @@ -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!'
Expand All @@ -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

Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/categories.yml
Expand Up @@ -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
48 changes: 32 additions & 16 deletions test/models/participant_test.rb
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

0 comments on commit 6ddacf8

Please sign in to comment.