Next interesting thing for my Evendy.ru app - feature request to generate and import events directly to the *.ics files.
Good starting point for this type of feature - nice iCalendar gem.
Let’s add a simple link to our Event page:
<a v-on:click="get_cal()" class="btn btn-link btn-danger">
Календарь
</a>
Great, next let’s write our get_cal method and will add it to the methods section:
get_cal: function () {
this.$http.post(this.$route.path + '/calendar', {}, {responseType: 'blob'})
.then((response) => {
let blob = new Blob([response.data], { type: 'text/calendar' })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'event.ics'
link.click()
})
.catch((err) => {
console.log(err)
})
},
According this example, we should prepare raw blob data on server side, and send it to the our frontend application in the response param.
But to simulate download, we need to create some temporary link object, with href which points to the our raw blob.
let blob = new Blob([response.data], { type: 'text/calendar' })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
Great, in the next step, let’s check our server side. Our CalendarCommand:
class Features::CalendarCommand < BaseCommand
step :generate
def generate(id:)
event = Event.find_by(id: id)
cal = Icalendar::Calendar.new
cal_event = Icalendar::Event.new
cal_event.dtstart = Icalendar::Values::DateTime.new(event.start_at)
cal_event.dtend = Icalendar::Values::DateTime.new(event.end_at)
cal_event.summary = event.title
cal_event.location = event.address
cal_event.uid = cal_event.url = "http://evendy.ru/events/#{event.to_param}"
if cal.add_event(cal_event)
cal.publish
Right(cal)
else
Left(error(I18n.t('errors.base')))
end
end
end
Here, we created FeaturesController and reloaded our run_command method with new calendar_response method:
def calendar_response(data)
send_data data.to_ical
end
And controller:
class FeaturesController < BaseController
def calendar
cal = run_command(Features::CalendarCommand, {id: params[:id]})
headers['Content-Type'] = 'text/calendar; charset=UTF-8'
end
private
def run_command(command, params)
command.run(params) do |m|
m.success {|object| calendar_response(object) }
m.failure {|errors| error_response(errors) }
end
end
end
That’s it. Let’s download generated file and add our event.