diff --git a/app/controllers/admin/members_controller.rb b/app/controllers/admin/members_controller.rb index 82f3f7b06..2147aed58 100644 --- a/app/controllers/admin/members_controller.rb +++ b/app/controllers/admin/members_controller.rb @@ -75,7 +75,6 @@ def create impressionist(@member, 'nieuwe lid') redirect_to(@member) else - # If the member hasn't filled in a study, again show an empty field @member.educations.build(id: '-1') if @member.educations.empty? diff --git a/app/controllers/api/calendars_controller.rb b/app/controllers/api/calendars_controller.rb index 49d713326..3141a5f2e 100644 --- a/app/controllers/api/calendars_controller.rb +++ b/app/controllers/api/calendars_controller.rb @@ -16,7 +16,7 @@ def show # end respond_to do |format| format.ics { - send_data create_calendar, + send_data create_personal_calendar, type: 'text/calendar', disposition: 'attachment', filename: "#{@member.first_name}_activities.ics" @@ -36,10 +36,21 @@ def index end # Not exposed to API directly, but through #show - def create_calendar + def create_personal_calendar @member = Member.find_by(calendar_id: params[:calendar_id]) - locale = I18n.locale # TODO werkt dit? - events = @member.activities.map { |a| IcalendarHelper.activityToEvent(a, locale) } - IcalendarHelper.createCalendar(events, locale).to_ical + @locale = I18n.locale # TODO werkt dit? + + # Convert activities to events, and mark activities where the member is + # is enrolled as reservist + @reservist_activity_ids = @member.reservist_activities.ids + events = @member.activities.map do |a| + if @reservist_activity_ids.include? a.id + a.name = "[RESERVIST] #{a.name}" + end + IcalendarHelper.activityToEvent(a, @locale) + end + + # Return the calendar + IcalendarHelper.createCalendar(events, @locale).to_ical end end diff --git a/app/models/member.rb b/app/models/member.rb index 9b5199843..716a34b91 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -16,6 +16,7 @@ class Member < ApplicationRecord validates :emergency_phone_number, presence: true, if: :underage? validates :email, presence: true, uniqueness: { case_sensitive: false }, format: { with: /\A.+@(?!(.+\.)*uu\.nl\z).+\..+\z/i } + validates :calendar_id, presence: true, uniqueness: true # An attr_accessor is basically a variable attached to the model but not stored in the database attr_accessor :require_student_id @@ -203,6 +204,12 @@ def groups return groups.values end + # We cannot enforce that a member is created with a calendar_id, but we can enforce that + # when a member is created or saved, a calendar_id is set before validation. + before_validation on: [:save, :create] do + self.calendar_id = SecureRandom.uuid if self.calendar_id.blank? + end + # Rails also has hooks you can hook on to the process of saving, updating or deleting. Here the join_date is automatically filled in on creating a new member # We also check for a duplicate study, and discard the duplicate if found. # (Not doing this would lead to a database constraint violation.) diff --git a/db/migrate/20240521180025_add_calendar_id_to_member.rb b/db/migrate/20240521180025_add_calendar_id_to_member.rb index da7f4da90..d9fa39ca1 100644 --- a/db/migrate/20240521180025_add_calendar_id_to_member.rb +++ b/db/migrate/20240521180025_add_calendar_id_to_member.rb @@ -1,5 +1,19 @@ class AddCalendarIdToMember < ActiveRecord::Migration[6.1] - def change + def up add_column :members, :calendar_id, :uuid + + # Populate existing records with a random UUID + Member.reset_column_information + Member.find_each do |record| + record.update_columns(calendar_id: SecureRandom.uuid) + end + + # Add a unique index to the UUID column, because why not + add_index :members, :calendar_id, unique: true + end + + def down + # Remove the UUID column + remove_column :members, :calendar_id end end diff --git a/db/seeds/members.rb b/db/seeds/members.rb index 9b51941fc..145c314c8 100644 --- a/db/seeds/members.rb +++ b/db/seeds/members.rb @@ -19,7 +19,7 @@ birth_date: Faker::Date.between(from: 28.years.ago, to: 16.years.ago), join_date: Faker::Date.between(from: 6.years.ago, to: Date.today), comments: (Faker::Boolean.boolean(true_ratio: 0.3) ? Faker::Hacker.say_something_smart : nil), - calendar_id: Faker::Boolean.boolean(true_ratio: 0.4) ? SecureRandom.uuid : nil + calendar_id: Faker::Internet.uuid ) puts(" -> #{ member.name } (#{ member.student_id })") diff --git a/db/structure.sql b/db/structure.sql index 1ab61df75..afccb6e24 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1450,6 +1450,13 @@ CREATE UNIQUE INDEX index_group_members_on_member_id_and_group_id_and_year ON pu CREATE INDEX index_impressions_on_user_id ON public.impressions USING btree (user_id); +-- +-- Name: index_members_on_calendar_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_members_on_calendar_id ON public.members USING btree (calendar_id); + + -- -- Name: index_members_on_email; Type: INDEX; Schema: public; Owner: - --