【问题标题】:fullcalendar passing js vars to rails and vice versafullcalendar 将 js vars 传递给 rails,反之亦然
【发布时间】:2016-03-23 06:08:39
【问题描述】:

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

如果我在 AJAX 中使用:url: the_event.recipientId + "/events/" + the_event.id 然后控制台告诉我: S​​tarted 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 来说,这要困难得多。浏览器应该根据 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

事件.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

【问题讨论】:

  • 好的,这只是对你的问题写作的建议:每个问题都应该是它自己的问题 - 你在这里写了四个问题。
  • 所以无论问题属于同一个代码,我都应该将它们以不同的标题分成 4 个问题,并在任何地方提供相同的代码?
  • 可能。 :) 我可能不会真正回答这些问题,因为它超出了我的主要知识领域......但我知道如果你试图一次问多个问题,有些人会变得非常烦躁。

标签: jquery ruby-on-rails ajax fullcalendar


【解决方案1】:

关于“这条线可以吗”线:

 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>

我不建议你真的这样做......谷歌一个更好的方法 - 必须有一些关于将设计集成到你的 js in rails 的教程。这里只是为了向您展示您的 js 和 ruby​​ 必须如何交互才能使您的 js 可以使用这些信息。

【讨论】:

  • 有一个名为 'gon' 的 gem,它允许您在控制器提供页面后通过实例化全局变量来从 JS 访问 ruby​​ 中的值。需要注意的一个问题是,您必须始终再次检查用户是否是他们声称的身份(即,在检索事件时,确保您在 CRUD 方法中检查事件属于用户),因为他们始终可以修改 JS 全局变量。
猜你喜欢
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
相关资源
最近更新 更多