I have a rails app. I'm trying to integrate the fullcalendar into my app. For testing I created manually an event which shows up in the calendar after sending over with as_json to the browser. When I try to move (update) the event the js works but I can't save it to the db thanks to routing problems. In the code below I have it hard coded, so it works this way.
If I use in the AJAX: url: the_event.recipientId + "/events/" + the_event.id
then the console tells me: Started POST "/users/1/1/events/1" --> no route matches. If I use url: "/events/" + the_event.id
then started POST "/events/1" --> no route matches. So now I'm using event.url that is sent over from event.rb, but it is hard coded.
How could I set the matching urls for the current_user in the AJAX POST(for this I also need to find recipient (user) from db) and PUT call? For the PUT (update) recipient and sender are already defined so with the as_json method the data will be sent over to the browser. Here my problem is to tell in the model (event.rb) if the current_user is the sender or the recipient and set the url without hard coding as it is now. For the POST it's way harder. Browser should figure out who the current_user (sender) is based on url or somehow, and on the top of that it should be able to pick an existing user (recipient) from the db. How can I do this second part?
/users/1/events/json
[{"id":1,
"recipientId":1,
"senderId":2,
"title":"cool",
"body":"hahahhahhhaha",
"start":"2015-12-15T17:03:05.110-08:00",
"end":"2015-12-15T19:03:05.111-08:00",
"allDay":null,
"recurring":false,
"url":"/users/1/events.1"}] //hard coded in rails model since there is no current_user in model level
event.js
var updateEvent;
var ready = function() {
$('#calendar').fullCalendar({
editable: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultView: 'month',
height: 500,
slotMinutes: 30,
eventSources: [{ url: '/users/:user_id/events', }], // IS THIS LINE OKAY?
timeFormat: 'h:mm t{ - h:mm t} ',
dragOpacity: "0.5",
eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc) {
return updateEvent(event);
},
eventResize: function(event, dayDelta, minuteDelta, revertFunc) {
return updateEvent(event);
select: function(start, end, allDay) {
var title = prompt('Event Title:');
$('#calendar').fullCalendar('renderEvent',
{
title: title,
start_at: start,
end_at: end,
allDay: allDay
},
true //making event stick
);
$.ajax({
type: "POST",
url: "/users/1/events",
data: { event: {
title: the_event.title,
start_at: "" + new Date(the_event.start).toUTCString(),
end_at: "" + new Date(the_event.end).toUTCString(),
body: the_event.body,
sender_id: the_event.senderId,
recipient_id: the_event.recipientId }
}
});
}
});
};
updateEvent = function(the_event) {
$.ajax({
type: "PUT",
url: the_event.url // used to be: the_event.recipientId + "/events/" + the_event.id, WHAT SHOULD I USE HERE?
data: { event: {
title: the_event.title,
start_at: "" + the_event.start,
end_at: "" + the_event.end,
body: the_event.body,
sender_id: the_event.senderId,
recipient_id: the_event.recipientId }
}
});
};
$(document).ready(ready);
$(document).on("page:load", ready);
events controller
class EventsController < ApplicationController
before_action :set_event, only: [:show, :edit, :update, :destroy]
def index
@events = current_user.events#.between(params['start'], params['end']) if (params['start'] && params['end'])
respond_to do |format|
format.html
format.json { render json: @events }
end
end
def show
respond_to do |format|
format.html
format.json { render json: @event }
end
end
def new
@event = Event.new
respond_to do |format|
format.html
format.js
end
end
def create
@event = Event.new(event_params)
@event.sender_id = current_user.id
respond_to do |format|
format.html
format.js
end
end
def edit
end
def update
respond_to do |format|
if @event.update_attributes(event_params)
format.html { redirect_to @event, notice: 'Event was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @event.errors, status: :unprocessable_entity }
end
end
end
def destroy
@event.destroy
respond_to do |format|
format.html { redirect_to user_events_path(current_user) }
format.json { head :no_content }
end
end
private
def set_event
@event = Event.find(params[:id])
end
def event_params
params.require(:event).permit(:recipient_id, :sender_id, :title, :body, :start_at, :end_at, :all_day)
end
end
event.rb
class Event < ActiveRecord::Base
belongs_to :recipient, class_name: "User", foreign_key: "recipient_id"
belongs_to :sender, class_name: "User", foreign_key: "sender_id"
scope :between_time, -> (start_time, end_time) do
where("? < start_at < ?", Event.format_date(start_time), Event.format_date(end_time))
end
scope :allevents, -> (u) { where('sender_id = ? OR recipient_id = ?', u.id, u.id) }
scope :between, -> (sender, recipient) do
where("(events.sender_id = ? AND events.recipient_id = ?) OR (tasks.sender_id = ? AND tasks.recipient_id = ?)", sender.id, recipient.id, recipient.id, sender.id)
end
def self.format_date(date_time)
Time.at(date_time.to_i).to_formatted_s(:db)
end
def as_json(options = {})
{ id: self.id,
recipientId: self.recipient_id,
senderId: self.sender_id,
title: self.title,
body: self.body || "",
start: start_at,
:end => end_at,
allDay: self.all_day,
recurring: false,
url: Rails.application.routes.url_helpers.user_event_path(self.recipient_id, self.id)
#self.recipient hard coded, it could be self.sender if self.sender == current_user
}
end
# def event_interlocutor(event)
# current_user == event.recipient ? event.recipient_id : event.sender_id
# end
end
See Question&Answers more detail:
os