Skip to content

Commit

Permalink
Add events and event organizers including tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
openbrian committed Aug 9, 2024
1 parent 1f14f5e commit c7f712d
Show file tree
Hide file tree
Showing 15 changed files with 459 additions and 1 deletion.
2 changes: 2 additions & 0 deletions app/abilities/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def initialize(user)
can [:create, :destroy], CommunityMember, :user_id => user.id
can [:destroy, :edit, :update], CommunityMember, :community => user_is_community_organizer
can [:create, :edit, :new, :update], Event, :community => user_is_community_organizer
can [:create], EventAttendance
can [:update], EventAttendance, :user_id => user.id
can [:close, :reopen], Note
can [:show, :edit, :update], :preference
can [:edit, :update], :profile
Expand Down
40 changes: 40 additions & 0 deletions app/controllers/event_attendances_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class EventAttendancesController < ApplicationController
layout "site"
before_action :authorize_web
before_action :set_event_attendance, :only => [:update]

authorize_resource

def create
attendance = EventAttendance.new(event_attendance_params)
if attendance.save
redirect_to event_path(attendance.event), :notice => t(".success")
else
redirect_to event_path(attendance.event), :alert => t(".failure")
end
end

def update
respond_to do |format|
if @event_attendance.update(update_params)
format.html { redirect_to @event_attendance.event, :notice => t(".success") }
else
format.html { redirect_to :edit, :alert => t(".failure") }
end
end
end

private

def set_event_attendance
@event_attendance = EventAttendance.find(params[:id])
end

def event_attendance_params
params.require(:event_attendance).permit(:event_id, :user_id, :intention)
end

def update_params
params.require(:event_attendance).permit(:intention)
end
end
7 changes: 7 additions & 0 deletions app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ def index
# GET /events/1.json
def show
@community = Community.friendly.find(params[:community_id]) if params[:community_id]
@my_attendance = EventAttendance.find_or_initialize_by(:event_id => @event.id, :user_id => current_user&.id)
@yes_check = @my_attendance.intention == EventAttendance::Intentions::YES ? "✓" : ""
@no_check = @my_attendance.intention == EventAttendance::Intentions::NO ? "✓" : ""
@maybe_check = @my_attendance.intention == EventAttendance::Intentions::MAYBE ? "✓" : ""
@yes_disabled = @my_attendance.intention == EventAttendance::Intentions::YES
@no_disabled = @my_attendance.intention == EventAttendance::Intentions::NO
@maybe_disabled = @my_attendance.intention == EventAttendance::Intentions::MAYBE
rescue ActiveRecord::RecordNotFound
@not_found_community = params[:community_id]
render :template => "communities/no_such_community", :status => :not_found
Expand Down
17 changes: 17 additions & 0 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
class Event < ApplicationRecord
belongs_to :community
has_many :event_organizers
has_many :event_attendances

scope :future, -> { where(:moment => Time.now.utc..) }
scope :past, -> { where(:moment => ...Time.now.utc) }
Expand Down Expand Up @@ -63,4 +64,20 @@ def organizers
def past?
moment < Time.now.utc
end

def attendees(intention)
EventAttendance.where(:event_id => id, :intention => intention)
end

def yes_attendees
attendees(EventAttendance::Intentions::YES)
end

def no_attendees
attendees(EventAttendance::Intentions::NO)
end

def maybe_attendees
attendees(EventAttendance::Intentions::MAYBE)
end
end
35 changes: 35 additions & 0 deletions app/models/event_attendance.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# == Schema Information
#
# Table name: event_attendances
#
# id :bigint(8) not null, primary key
# user_id :bigint(8) not null
# event_id :bigint(8) not null
# intention :enum not null
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_event_attendances_on_event_id (event_id)
# index_event_attendances_on_user_id (user_id)
# index_event_attendances_on_user_id_and_event_id (user_id,event_id) UNIQUE
#
# Foreign Keys
#
# fk_rails_... (event_id => events.id)
# fk_rails_... (user_id => users.id)
#

class EventAttendance < ApplicationRecord
module Intentions
YES = "Yes".freeze
NO = "No".freeze
MAYBE = "Maybe".freeze
ALL_INTENTIONS = [YES, NO, MAYBE].freeze
end
validates :intention, :inclusion => { :in => Intentions::ALL_INTENTIONS }

belongs_to :event
belongs_to :user
end
42 changes: 42 additions & 0 deletions app/views/events/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,24 @@
<%= render :partial => "events/event_property", :locals => { :name => t(".description"), :value => @event.description } %>
</table>
</div>
<div>
<p><%= t(".people_are_going", :count => @event.yes_attendees.size) %></p>
<p><%= t(".are_you_going") %></p>
<% if current_user %>
<%= form_with :model => @my_attendance do |form| %>
<%= form.hidden_field(:event_id, :value => @event.id) %>
<%= form.hidden_field(:user_id, :value => current_user&.id) %>
<%= form.submit :name => "event_attendance[intention]", :value => @yes_check + t(".going_yes"), :disabled => @yes_disabled %>
<%= form.submit :name => "event_attendance[intention]", :value => @no_check + t(".going_no"), :disabled => @no_disabled %>
<%= form.submit :name => "event_attendance[intention]", :value => @maybe_check + t(".going_maybe"), :disabled => @maybe_disabled %>
<% end %>
<% else %>
<p>
<%# TODO: Use login_path %>
<%= t(".login_to_rsvp") %>
</p>
<% end %>
</div>
</div>
<div class="col-sm">
<%= tag.div "",
Expand All @@ -43,3 +61,27 @@
</div>
</div>
</div>
<div class="row">
<div class="row">
<div class="col-sm">
<strong><%= t(".who_yes") %></strong>
<div>
<% @event.yes_attendees.each do |attendance| %>
<%= render :partial => "users/user_card", :locals => { :user => attendance.user } %>
<% end %>
</div>
<strong><%= t(".who_maybe") %></strong>
<div>
<% @event.maybe_attendees.each do |attendance| %>
<%= render :partial => "users/user_card", :locals => { :user => attendance.user } %>
<% end %>
</div>
<strong><%= t(".who_no") %></strong>
<div>
<% @event.no_attendees.each do |attendance| %>
<%= render :partial => "users/user_card", :locals => { :user => attendance.user } %>
<% end %>
</div>
</div>
</div>
</div>
2 changes: 1 addition & 1 deletion app/views/layouts/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
<% end %>
<li><%= link_to t("layouts.gps_traces"), traces_path, :class => "dropdown-item" %></li>
<li><%= link_to t("layouts.user_diaries"), diary_entries_path, :class => "dropdown-item" %></li>
<li><%= link_to t("layouts.communities"), communities_path, :class => "dropdown-item" %></li>
<li><%= link_to t("layouts.communities"), communities_index_path, :class => "dropdown-item" %></li>
<li><%= link_to t("layouts.copyright"), copyright_path, :class => "dropdown-item" %></li>
<li><%= link_to t("layouts.help"), help_path, :class => "dropdown-item" %></li>
<li><%= link_to t("layouts.about"), about_path, :class => "dropdown-item" %></li>
Expand Down
23 changes: 23 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,13 @@ en:
not_found:
title: File not found
description: Couldn't find a file/directory/API operation by that name on the OpenStreetMap server (HTTP 404)
event_attendances:
create:
success: Attendance was successfully saved.
failure: Attendance could not be saved.
update:
success: Attendance was successfully updated.
failure: Attendance could not be updated.
events:
create:
success: Event was created successfully.
Expand All @@ -795,14 +802,27 @@ en:
new:
new: "New Event"
show:
are_you_going: "Are you going?"
description: "Description"
directions_to: "Directions to this location."
edit: "Edit"
going_maybe: "Maybe"
going_no: "No"
going_yes: "Yes"
hosted_by: "Hosted by"
location: "Location"
login_to_rsvp: "Login to RSVP."
organized_by: "Organized by"
past: "Event is in the past."
people_are_going:
0: "" # TODO: Not working, but can't use "zero" due to lint.
1: "1 person is going." # TODO: Not working.
one: "1 person is going."
other: "%{count} people are going"
when: "When"
who_yes: "Going"
who_no: "Not Going"
who_maybe: "Might Go"
update:
success: "The event was successfully updated."
failure: "The event was not updated."
Expand Down Expand Up @@ -1717,6 +1737,9 @@ en:
home: Go to Home Location
logout: Log Out
log_in: Log In
log_in_tooltip: Log in with an existing account
communities: Communities
events: Events
sign_up: Sign Up
start_mapping: Start Mapping
edit: Edit
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@
resources :community_members, :only => [:create, :destroy, :edit, :new, :update]
get "/community_members" => "community_members#create", :as => "login_to_join"
resources :events
resources :event_attendances

# errors
match "/400", :to => "errors#bad_request", :via => :all
Expand Down
18 changes: 18 additions & 0 deletions db/migrate/20240730234421_create_event_attendances.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class CreateEventAttendances < ActiveRecord::Migration[7.0]
def up
create_enum :event_attendances_intention_enum, %w[Maybe No Yes]
create_table :event_attendances do |t|
t.references :user, :foreign_key => true, :null => false, :index => true
t.references :event, :foreign_key => true, :null => false, :index => true
t.column :intention, :event_attendances_intention_enum, :null => false

t.timestamps
end
add_index :event_attendances, [:user_id, :event_id], :unique => true
end

def down
drop_table :event_attendances
drop_enum :event_attendances_intention_enum
end
end
Loading

0 comments on commit c7f712d

Please sign in to comment.