Skip to content

Commit d3f51af

Browse files
committed
chore: remove empty code changes in locatable_location and one modules
1 parent 9755135 commit d3f51af

File tree

3 files changed

+139
-3
lines changed

3 files changed

+139
-3
lines changed

app/models/better_together/geography/locatable_location.rb

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ class LocatableLocation < ApplicationRecord
99
belongs_to :locatable, polymorphic: true
1010
belongs_to :location, polymorphic: true, optional: true
1111

12-
validates :name, presence: true, if: :simple_location?
13-
validate :at_least_one_location_source
12+
# If a persisted nested location is submitted with all empty fields, mark it
13+
# for destruction so accepts_nested_attributes_for with allow_destroy will remove it
14+
before_validation :mark_for_destruction_if_empty
15+
16+
# Validate name only for simple locations and not when marked for destruction
17+
validates :name, presence: true, if: -> { simple_location? && !marked_for_destruction? }
18+
validate :at_least_one_location_source, unless: :marked_for_destruction?
1419

1520
def self.permitted_attributes(id: false, destroy: false)
1621
super + %i[
@@ -129,7 +134,19 @@ def self.available_buildings_for(context = nil) # rubocop:todo Metrics/MethodLen
129134

130135
private
131136

137+
def mark_for_destruction_if_empty
138+
name_blank = name.blank?
139+
location_blank = location.blank?
140+
141+
# If both the simple name and structured location are blank, mark for destruction
142+
# for both new and persisted records so validations won't block form submission.
143+
mark_for_destruction if name_blank && location_blank
144+
end
145+
132146
def at_least_one_location_source
147+
# If this record is scheduled for destruction or otherwise empty, don't add errors here
148+
return if marked_for_destruction?
149+
133150
sources = [name.present?, location.present?]
134151
return if sources.any?
135152

app/models/concerns/better_together/geography/locatable/one.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,18 @@ module One
1212
class_name: 'BetterTogether::Geography::LocatableLocation',
1313
as: :locatable
1414

15+
# Reject nested location attributes when all relevant fields are blank so
16+
# we don't build an invalid empty LocatableLocation during create/update.
17+
# Only reject when this is a new nested record (no id) and all meaningful
18+
# fields are blank. Persisted records with blank fields should be allowed
19+
# through so they can be marked for destruction by the model callback.
1520
accepts_nested_attributes_for :location,
16-
allow_destroy: true, reject_if: :blank?
21+
allow_destroy: true,
22+
reject_if: ->(attrs) {
23+
attrs.blank? || (
24+
attrs['id'].blank? && attrs['name'].blank? && attrs['location_id'].blank? && attrs['location_type'].blank?
25+
)
26+
}
1727
end
1828

1929
class_methods do

spec/requests/better_together/events_controller_spec.rb

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,113 @@
128128
end
129129
end
130130
end
131+
132+
describe 'creating events with different location types' do
133+
let(:locale) { I18n.default_locale }
134+
135+
context 'as platform manager', :as_platform_manager do
136+
it 'creates an event with a simple (name) location' do
137+
params = {
138+
event: {
139+
name: 'Simple Location Event',
140+
starts_at: 1.day.from_now.iso8601,
141+
identifier: SecureRandom.uuid,
142+
privacy: 'public',
143+
location_attributes: {
144+
name: 'Community Hall'
145+
}
146+
},
147+
locale: locale
148+
}
149+
150+
post better_together.events_path(locale: locale), params: params
151+
152+
expect(response).to have_http_status(:found)
153+
event = BetterTogether::Event.order(:created_at).last
154+
expect(event).to be_present
155+
expect(event.location).to be_present
156+
expect(event.location.name).to eq('Community Hall')
157+
expect(event.location.location).to be_nil
158+
end
159+
160+
it 'creates an event with an Address location' do
161+
address = create(:better_together_address, privacy: 'public')
162+
163+
params = {
164+
event: {
165+
name: 'Address Location Event',
166+
starts_at: 1.day.from_now.iso8601,
167+
identifier: SecureRandom.uuid,
168+
privacy: 'public',
169+
location_attributes: {
170+
location_id: address.id,
171+
location_type: 'BetterTogether::Address'
172+
}
173+
},
174+
locale: locale
175+
}
176+
177+
post better_together.events_path(locale: locale), params: params
178+
179+
expect(response).to have_http_status(:found)
180+
event = BetterTogether::Event.order(:created_at).last
181+
expect(event).to be_present
182+
expect(event.location).to be_present
183+
expect(event.location.location_type).to eq('BetterTogether::Address')
184+
expect(event.location.address).to be_present
185+
expect(event.location.address.id).to eq(address.id)
186+
end
187+
188+
it 'creates an event with a Building location' do
189+
manager_user = BetterTogether::User.find_by(email: '[email protected]') ||
190+
create(:better_together_user, :confirmed, :platform_manager, email: '[email protected]')
191+
building = create(:better_together_infrastructure_building, creator: manager_user.person, privacy: 'private')
192+
193+
params = {
194+
event: {
195+
name: 'Building Location Event',
196+
starts_at: 1.day.from_now.iso8601,
197+
identifier: SecureRandom.uuid,
198+
privacy: 'public',
199+
location_attributes: {
200+
location_id: building.id,
201+
location_type: 'BetterTogether::Infrastructure::Building'
202+
}
203+
},
204+
locale: locale
205+
}
206+
207+
post better_together.events_path(locale: locale), params: params
208+
209+
expect(response).to have_http_status(:found)
210+
event = BetterTogether::Event.order(:created_at).last
211+
expect(event).to be_present
212+
expect(event.location).to be_present
213+
expect(event.location.location_type).to eq('BetterTogether::Infrastructure::Building')
214+
expect(event.location.building).to be_present
215+
expect(event.location.building.id).to eq(building.id)
216+
end
217+
218+
it 'creates a draft event with no location assigned' do
219+
params = {
220+
event: {
221+
name: 'Draft Event Without Location',
222+
identifier: SecureRandom.uuid,
223+
privacy: 'public'
224+
# intentionally omit starts_at to keep it a draft and omit location_attributes
225+
},
226+
locale: locale
227+
}
228+
229+
post better_together.events_path(locale: locale), params: params
230+
231+
expect(response).to have_http_status(:found)
232+
event = BetterTogether::Event.order(:created_at).last
233+
expect(event).to be_present
234+
expect(event.starts_at).to be_nil
235+
expect(event).to be_draft
236+
expect(event.location).to be_nil
237+
end
238+
end
239+
end
131240
end

0 commit comments

Comments
 (0)