fullcalendar将js变量传递给rails,反之亦然

时间:2015-12-16 22:26:34

标签: jquery ruby-on-rails ajax fullcalendar

我有一个rails应用程序。我正在尝试将fullcalendar集成到我的应用中。为了测试,我手动创建了一个事件,该事件在使用as_json发送到浏览器后显示在日历中。当我尝试移动(更新)事件js工作但由于路由问题我无法将其保存到数据库。在下面的代码中,我对其进行了硬编码,因此它可以这样工作。

如果我在AJAX中使用:url: the_event.recipientId + "/events/" + the_event.id 然后控制台告诉我:开始POST" / users / 1/1 / events / 1" - >没有路线匹配。如果我使用url: "/events/" + the_event.id,则启动POST" / events / 1" - >没有路线匹配。所以现在我使用从event.rb发送的event.url,但它是硬编码的。

如何在AJAX POST中为current_user设置匹配的url(为此我还需要从db中找到收件人(用户))和PUT调用?对于PUT(更新),已经使用as_json方法定义了收件人和发件人,数据将被发送到浏览器。这里我的问题是在模型(event.rb)中告诉current_user是发件人还是收件人,并设置url而不像现在那样进行硬编码。对于POST来说,它更难。浏览器应该确定current_user(sender)是基于url或者某种方式的,并且最重要的是它应该能够从db中选择现有用户(收件人)。我该怎么做第二部分?

/用户/ 1 /事件/ 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

1 个答案:

答案 0 :(得分:2)

关于“这条线是否正确”行:

 eventSources: [{ url: '/users/:user_id/events', }], // IS THIS LINE OKAY?

你正在混合你的js和ruby,这就是为什么它不起作用。 '/users/:user_id/events'不是路线。 '/users/12234/events是一条路线。你的js不明白:user_id是什么 - &gt;你必须在那里真正设置一个真实的用户ID。

我注意到控制器代码中缺少的一件事就是您实例化实际用户的任何地方......你有current_user吗? (即你是否正在使用设计用户登录?)如果是这样,那么你可以合理地使用它:

 eventSources: [{ url: '/users/<%= current_user.id %>/events', }], // IS THIS LINE OKAY?

然而 - 我注意到你的js文件被命名为“events.js”,因此根本不是与ruby相关的 - 在这种情况下上面也不会起作用,因为普通的js文件中没有ruby。 / p>

您需要在erb模板中设置某种javascript环境变量... javascript代码可以访问。

这是我自己的知识,但我会说一个可怕的,讨厌的黑客会做的事情:

<script>
   var user_id = <%= current_user.id %>
</script>

我不建议您实际执行此操作...谷歌更好的方式 - 必须有一些关于将设备集成到您的js中的教程。这只是为了向您展示您的js和ruby必须如何相互作用才能使您的js可以获得信息。