Try with:
index = 0
events.each do |event|
# ...
index += 1 if event.new_record?
end
A bit too much procedural for my tastes, but it should do the job
Question
So my website right now has a list of addresses with a drop down list of Locations
. The Locations
are indexed when being created, however it is changing their index when the Location gets updated. So Essentially the issue is say I want to change Location 1
. Say I also have 6 Locations. When I press Update on Location 1
the Location
instance moves to the end of the index(#6). I know where the issue is, but I'm not sure how to fix it.
My Show Page
.dropdown-panel
.dropdown-info
- if events.any?
%a.button.dropdown{"data-dropdown" => "drop1"} Locations
- else
%a.button No Locations
%ul#drop1.f-dropdown{"data-dropdown-content" => "", "data-tab" => ''}
- events.each_with_index do |event, index|
%li
%a#dropDownNav{:href => "#panel1-#{index + 1}"} Location #{index + 1}
.dropdown-add
- if current_user
%a.button#add_event{:href => "#new_event"} +
.tabs-content
- events.each_with_index do |event, index| <---I feel this is the issue(See Below)
-if event.user_id == current_user.id
.content{id: "panel1-#{index + 1}", class: index.zero? ? 'active' : ''}
= render 'form', event: event, index: index
- if current_user
.content{id: "new_event"}
= render 'form'
I think the above has the issue under the .tabs-content. The each_with_index assigns a new index every time that list is reloaded. I can't figure out how to change it to only assign an index to the new events only.
I'm not sure if the _form.html.haml partial will help, but here it is...
.form-content
- if current_user
/ - event.errors.each do |attr, msg|
/ = msg
= form_for event do |f|
%fieldset.location-entry
- title = f.object.new_record? ? "New Location" : "Location #{index + 1}"
= f.hidden_field :date, value: date
.alert-box.alert{"data-alert" => ""}
An address is required
%a.close{:href => "#"} ×
%h4= title
- flash.each do |name, msg|
= content_tag :div, msg, class: name
.fields
%dl
%dt
= f.label :address, "Enter Location", :required => true
%dd
= f.text_field :address, placeholder: 'Enter Address', class: 'address-input'
%dl
%dt
= f.label :start, "Enter Timeframe"
%dd.time-entry
#timestart= f.time_select :start, { combined: true, minute_step: 15, ampm: true, :time_separator => ""}
.to
%p to
#time_end= f.time_select :end_time, { combined: true, minute_step: 15, ampm: true, :time_separator => ""}
%dl.entry-submit
- if !event.address
= f.submit 'Enter Location', class: 'button', id: 'newevent'
- if event.address
= f.submit 'Update Location', class: 'button', id: 'updateevent', method: :put
.remove-location
= link_to 'Remove Location', event, method: :delete, data: { confirm: 'Are you sure?' }
Also let me know if this is a good job of explaining it or what I would need to add to make it better.
My Events Controller
class EventsController < ApplicationController
before_action :verify_user_or_admin
def update
params[:event].parse_time_select! :start
params[:event].parse_time_select! :end_time
event = current_user.events.find(params[:id])
respond_to do |format|
if event.update(event_params)
format.html { redirect_to event_path(event.start.to_date), notice: 'Event was successfully updated.' }
format.json { head :no_content }
else
format.html { redirect_to event_path(event.date), alert: 'There was an error creating your event.' }
format.json { render json: event.errors, status: :unprocessable_entity }
end
end
end
def show
if current_user
@locations= current_user.events.where( "date(start) = ?", date).all
elsif current_admin
@locations = Event.where("date(start) = ?", date).all
end
@hash = Gmaps4rails.build_markers(@locations) do |location, marker|
marker.lat(location.latitude)
marker.lng(location.longitude)
marker.infowindow render_to_string(:partial => "info", :locals => { :event => location })
marker.picture({
"url" => ActionController::Base.helpers.image_path('icon-marker-truck.gif'),
"width" => 28,
"height" => 40
})
end
end
def refresh
render :partial => "welcome/info"
end
def new
end
def create
params[:event].parse_time_select! :start
params[:event].parse_time_select! :end_time
event.attributes = event_params
if event.save
redirect_to event_path(event.start.to_date)
flash[:notice] = "Event created successfully"
else
flash[:alert] = "There was an error creating your event"
render :new
end
end
def date
@date ||= params[:id].present? ? Date.parse(params[:id]): Date.today
rescue ArgumentError
@date = Date.today
end
helper_method :date
def days
(date.beginning_of_week(:sunday)..date.end_of_week(:sunday))
end
helper_method :days
def event
if current_user
@event ||= current_user.events.build(start: date, end_time: date)
end
end
helper_method :event
def events
@events ||= current_user.events.for_day(date)
end
helper_method :events
def destroy
event = current_user.events.find(params[:id])
event.destroy
redirect_to event_path(event.start.to_date), :notice => "Your event has been deleted"
end
private
def event_params
params.require(:event).permit(:start, :end_time, :address, :date)
end
end
Solution
Try with:
index = 0
events.each do |event|
# ...
index += 1 if event.new_record?
end
A bit too much procedural for my tastes, but it should do the job