Skip to content

Commit 1453e90

Browse files
authored
Feature/event hosts (#1049)
- adds event_host migration and model - an event can now accept nested attributes for its host - updates to the event create form to accept and pass its host type and id
2 parents 1597fce + ff27143 commit 1453e90

File tree

30 files changed

+277
-78
lines changed

30 files changed

+277
-78
lines changed

app/controllers/better_together/events_controller.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ class EventsController < FriendlyResourceController
88
Rails.application.eager_load!
99
end
1010

11+
before_action :build_event_hosts, only: :new
12+
1113
def index
1214
@draft_events = @events.draft
1315
@upcoming_events = @events.upcoming
@@ -16,6 +18,29 @@ def index
1618

1719
protected
1820

21+
def build_event_hosts # rubocop:disable Metrics/AbcSize
22+
return unless params[:host_id].present? && params[:host_type].present?
23+
24+
return unless event_host_class
25+
26+
policy_scope = Pundit.policy_scope!(current_user, event_host_class)
27+
host_record = policy_scope.find_by(id: params[:host_id])
28+
return unless host_record
29+
30+
resource_instance.event_hosts.build(
31+
host_id: params[:host_id],
32+
host_type: params[:host_type]
33+
)
34+
end
35+
36+
def event_host_class
37+
param_type = params[:host_type]
38+
39+
# Allow-list only specific classes to be set as host for an event
40+
valid_host_types = BetterTogether::HostsEvents.included_in_models
41+
valid_host_types.find { |klass| klass.to_s == param_type }
42+
end
43+
1944
def resource_class
2045
::BetterTogether::Event
2146
end

app/helpers/better_together/events_helper.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,12 @@
33
module BetterTogether
44
# View helpers for events
55
module EventsHelper
6+
# Return hosts for an event that the current user is authorized to view.
7+
# Keeps view markup small and centralizes the policy logic for testing.
8+
def visible_event_hosts(event)
9+
return [] unless event.respond_to?(:event_hosts)
10+
11+
event.event_hosts.map { |eh| eh.host if policy(eh.host).show? }.compact
12+
end
613
end
714
end

app/models/better_together/community.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ module BetterTogether
44
# A gathering
55
class Community < ApplicationRecord
66
include Contactable
7-
include Host
7+
include HostsEvents
88
include Identifier
99
include Infrastructure::BuildingConnections
1010
include Joinable
11+
include Permissible
12+
include PlatformHost
1113
include Protected
1214
include Privacy
13-
include Permissible
1415
include Metrics::Viewable
1516

1617
belongs_to :creator,

app/models/better_together/event.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@ class Event < ApplicationRecord
77
include Categorizable
88
include Creatable
99
include FriendlySlug
10+
include Identifier
1011
include Geography::Geospatial::One
1112
include Geography::Locatable::One
12-
include Identifier
13+
include Metrics::Viewable
1314
include Privacy
1415
include TrackedActivity
15-
include Viewable
1616

1717
attachable_cover_image
1818

1919
categorizable(class_name: 'BetterTogether::EventCategory')
2020

21+
has_many :event_hosts
22+
2123
# belongs_to :address, -> { where(physical: true, primary_flag: true) }
2224
# accepts_nested_attributes_for :address, allow_destroy: true, reject_if: :blank?
2325
# delegate :geocoding_string, to: :address, allow_nil: true
@@ -27,11 +29,14 @@ class Event < ApplicationRecord
2729
translates :description, backend: :action_text
2830

2931
validates :name, presence: true
30-
validates :starts_at, presence: true
3132
validates :registration_url, format: { with: URI::DEFAULT_PARSER.make_regexp(%w[http https]) }, allow_blank: true,
3233
allow_nil: true
3334
validate :ends_at_after_starts_at
3435

36+
before_validation :set_host
37+
38+
accepts_nested_attributes_for :event_hosts, reject_if: :all_blank
39+
3540
scope :draft, lambda {
3641
start_query = arel_table[:starts_at].eq(nil)
3742
where(start_query)
@@ -52,11 +57,18 @@ def self.permitted_attributes(id: false, destroy: false)
5257
starts_at ends_at registration_url
5358
] + [
5459
{
55-
address_attributes: BetterTogether::Address.permitted_attributes(id: true)
60+
address_attributes: BetterTogether::Address.permitted_attributes(id: true),
61+
event_hosts_attributes: BetterTogether::EventHost.permitted_attributes(id: true)
5662
}
5763
]
5864
end
5965

66+
def set_host
67+
return if event_hosts.any?
68+
69+
event_hosts.build(host: creator)
70+
end
71+
6072
def schedule_address_geocoding
6173
return unless should_geocode?
6274

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
module BetterTogether
4+
# Join an event to its host
5+
class EventHost < ApplicationRecord
6+
belongs_to :event, class_name: 'BetterTogether::Event'
7+
belongs_to :host, polymorphic: true
8+
9+
def self.permitted_attributes(id: false, destroy: false)
10+
super + %i[
11+
host_id host_type event_id
12+
]
13+
end
14+
end
15+
end

app/models/better_together/person.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def self.primary_community_delegation_attrs
1212
include Author
1313
include Contactable
1414
include FriendlySlug
15+
include HostsEvents
1516
include Identifier
1617
include Identity
1718
include Member
@@ -101,6 +102,10 @@ def description_html(locale: I18n.locale)
101102
super || description
102103
end
103104

105+
def valid_event_host_ids
106+
[id] + member_communities.pluck(:id)
107+
end
108+
104109
def handle
105110
slug
106111
end

app/models/better_together/platform.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
module BetterTogether
66
# Represents the host application and it's peers
77
class Platform < ApplicationRecord
8-
include Host
8+
include PlatformHost
99
include Identifier
1010
include Joinable
1111
include Permissible
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
module BetterTogether
4+
# Concern that when included gives the model access to events through event_host records
5+
# This module must be included in a model to permit assigning instances as an event host
6+
module HostsEvents
7+
extend ActiveSupport::Concern
8+
9+
included do
10+
has_many :event_hosts, as: :host
11+
has_many :hosted_events, through: :event_hosts, source: :event
12+
end
13+
14+
def self.included_in_models
15+
included_module = self
16+
Rails.application.eager_load! if Rails.env.development? # Ensure all models are loaded
17+
ActiveRecord::Base.descendants.select { |model| model.included_modules.include?(included_module) }
18+
end
19+
end
20+
end

app/models/concerns/better_together/host.rb renamed to app/models/concerns/better_together/platform_host.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module BetterTogether
44
# Concern that when included allows model to be set as host
5-
module Host
5+
module PlatformHost
66
extend ActiveSupport::Concern
77

88
included do

app/policies/better_together/community_policy.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ def update?
2222
user.present? && (permitted_to?('manage_platform') || permitted_to?('update_community', record))
2323
end
2424

25+
def create_events?
26+
update? &&
27+
BetterTogether::EventPolicy.new(user, BetterTogether::Event.new).create?
28+
end
29+
2530
def edit?
2631
update?
2732
end

0 commit comments

Comments
 (0)