我有一个rails应用程序。我正在尝试将完整日历集成到我的应用程序中。为了进行测试,我手动创建了一个事件,该事件在用as_json发送到浏览器后显示在日历中。当我试图移动(更新)事件时,js可以工作,但由于路由问题,我无法将其保存到db。在下面的代码中,我对它进行了硬编码,所以它是这样工作的。
如果我在AJAX中使用:url: the_event.recipientId + "/events/" + the_event.id
然后控制台告诉我:Started POST"/users/1/1/events/1"-->没有路由匹配。如果我使用url: "/events/" + the_event.id
,则启动POST"/events/1"-->无路由匹配。所以现在我使用的是event.rb发送的event.url,但它是硬编码的。
我如何在AJAX POST中为current_user设置匹配的url(为此,我还需要从数据库中查找收件人(用户))和PUT调用?对于PUT(更新),已经定义了接收方和发送方,因此使用as_json方法,数据将被发送到浏览器。在这里,我的问题是在模型(event.rb)中判断current_user是发送方还是接收方,并在没有像现在这样硬编码的情况下设置url。对于POST来说,这要困难得多。浏览器应该根据url或以某种方式确定current_user(发送方)是谁,最重要的是,它应该能够从数据库中选择一个现有用户(接收方)。我该怎么做第二部分?
/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);
事件控制器
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
关于"这行行行吗"行:
eventSources: [{ url: '/users/:user_id/events', }], // IS THIS LINE OKAY?
你把js和ruby搞混了,这就是它不起作用的原因。'/users/:user_id/events'
不是路由。'/users/12234/events
是一条路由。你的js不明白:user_id
是什么->你必须在里面放一个真正的用户id。
我注意到控制器代码中缺少的一件事是实例化实际用户的任何地方。。。你有current_user
吗?(也就是说,你是在使用设备让用户登录吗?)如果是的话,那么你可以合理地使用这个:
eventSources: [{ url: '/users/<%= current_user.id %>/events', }], // IS THIS LINE OKAY?
然而,我注意到您的js文件名为"events.js",因此根本与ruby无关——在这种情况下,上述内容也不起作用,因为普通js文件中没有ruby。
您需要在erb模板中设置某种javascript环境变量。。。javascript代码可以访问的。
据我所知,这越来越不确定,但我想说,一个可怕的、令人讨厌的黑客会做一些类似的事情:
<script>
var user_id = <%= current_user.id %>
</script>
我不建议你真的这么做。。。谷歌是一个更好的方法——必须有一些教程来将design集成到rails中的js中。这里只是向您展示您的js和ruby必须如何交互,以便信息可供js使用。