0

我正在尝试使 Sinatra 应用程序中的代码在 Rails 上下文中工作。Sinatra 应用程序使用 ajax 请求来触发 Sinatra 路由/控制器操作。例如,如果您在 javascript 模型上触​​发新函数

   new: function() {
      var _this = this;

      $.ajax({
        url: "/gamestart",
        type: "POST",  
     ....

它将触发 Sinatra 应用程序中的路由/控制器代码

   post "/new" do

   end

当我尝试在 Rails 中进行这项工作时,我收到 500 内部服务器错误。在我的 Rails 应用程序中,new_game 按钮触发对 Rails 路由的 ajax 请求,该路由触发控制器操作,并且该控制器操作使用 Rails 模型从数据库中获取数据。出于某种原因,这似乎不是在 Rails 中执行此操作的正确方法,我想知道这是否是我收到服务器错误的原因

   GET http://localhost:3000/gamestart 500 (Internal Server Error)

如果可能,您能否告诉我在下面概述的一系列操作中出现错误的位置以及我可能会采取哪些措施来解决它。

1点击新游戏按钮触发'startNewGame'方法

'click #new_game': 'startNewGame',

2 startNewGame 方法调用 Game 模型上的方法

 startNewGame: function() {
          this.model.new();
        },

3 Game 模型中的新方法向 url '/gamestart' 发出 GET 请求。我还尝试了发布请求。我不知道为什么它需要一个发布请求,但都没有奏效。(在原始的 Sinatra 应用程序中,gamestart url 立即进入函数 post '/gamestart' do...)

 new: function() {
      var _this = this;
  $.ajax({
    url: "/gamestart",
    type: "GET",              \\\ also tried POST
    success: function(response) {
      var json = $.parseJSON(response);

      _this.set({lost: false});
      _this.set({win: false});
      _this.trigger("gameStartedEvent", json);
    }
  })
},

4我将 url 定向到 Rails 路由器文件中的控制器操作

match 'gamestart' => 'locations#gamestart', :via => :get

注意,在最初的 Sinatra 应用程序中,路由和控制器动作是结合在一起的

5 location_controller.rb的gamestart方法

    def gamestart 
       word = Word.get_random
       masquerade_word = Word.masquerade(word)
       session[:word] = word
       session[:incorrect_guesses] = 0
       session[:chars_left] = word.size
       session[:revealed_word] = masquerade_word
       {:word => masquerade_word}.to_json
    end

6词模型 Word.rb 上的 get_random 方法,从位置控制器调用

   def get_random
      words = []
      locations = Location.all (this pulls up the names of the locations from the db)
      locations.each do |e|
        words << e.name
      end 
      words.sample
    end

错误信息

GET http://localhost:3000/gamestart 500 (Internal Server Error) jquery.js:8215
XHR finished loading: "http://localhost:3000/gamestart". jquery.js:8215
send jquery.js:8215
jQuery.extend.ajax jquery.js:7767
window.Game.Backbone.Model.extend game.js:27
window.OptionsView.Backbone.View.extend.startNewGame optionsView.js:14
jQuery.event.dispatch jquery.js:3062
elemData.handle.eventHandle

请注意,在原始 Sinatra 应用程序中,路由和控制器操作以通常的 Sinatra 方式组合在一起

 post "/gamestart" do
   word = Word.get_random
   masquerade_word = Word.masquerade(word)
   session[:word] = word
   session[:incorrect_guesses] = 0
   session[:chars_left] = word.size
   session[:revealed_word] = masquerade_word
   {:word => masquerade_word}.to_json
end

更新 500 错误似乎是由缺少模板触发的。位置控制器中的这个方法没有渲染任何东西。它没有视图文件。因此,我更改了控制器以使其成为 respond_to :json,然后在操作结束时使用 respond_with,但这触发了 406 错误。

   def gamestart 
       word = Word.get_random
       masquerade_word = Word.masquerade(word)
       session[:word] = word
       session[:incorrect_guesses] = 0
       session[:chars_left] = word.size
       session[:revealed_word] = masquerade_word
       {:word => masquerade_word}.to_json
    end

变成 现在触发 406 错误

    respond_to :json

    def gamestart 
       word = Word.get_random
       masquerade_word = Word.masquerade(word)
       session[:word] = word
       session[:incorrect_guesses] = 0
       session[:chars_left] = word.size
       session[:revealed_word] = masquerade_word
       plainvariable = {:word => masquerade_word}.to_json    ###changed
       respond_with plainvariable                          ###changed
    end
4

1 回答 1

4

您说您的gamestart控制器方法由于缺少模板而导致服务器错误。如果我们看一下那个控制器方法:

def gamestart 
  #...
  {:word => masquerade_word}.to_json
end

我们看到它返回一个 JSON 字符串,但它忽略了渲染任何内容。您不调用任何渲染或重定向方法,因此 Rails 很有帮助(哈哈)假设您要渲染gamestart视图模板;但是,你没有这样的东西,所以你得到一个错误。

你应该渲染你的 JSON,而不是返回它;更像这样的东西:

def gamestart
  #...
  render :json => { :word => masquerade_word }
end
于 2013-01-13T06:37:13.927 回答