【问题标题】:Error when saving a Backbone.js model with Rails使用 Rails 保存 Backbone.js 模型时出错
【发布时间】:2011-08-21 07:54:10
【问题描述】:

我有一个项目对象的 Backbone.js 集合和模型:

window.Project = Backbone.Model.extend();

window.Projects = Backbone.Collection.extend({
    model: Project, 
    url: '/projects'
});

我已经设置了一个 Rails 控制器来响应 Backbone.js 集合:

class ProjectsController < ApplicationController

    def index
        render :json => Project.all
    end

    def create
        project = Project.create! params
        render :json => project
    end

end

索引工作正常,我在我的网络应用程序中获得了一个项目列表。问题是,如果我尝试在 Projects 集合上创建模型,我会从服务器收到 500 错误。

服务器上的错误信息如下:

Started POST "/projects" for 127.0.0.1 at 2011-08-21 08:27:56 +0100
  Processing by ProjectsController#create as JSON
  Parameters: {"title"=>"another test"}
Completed 500 Internal Server Error in 16ms

ActiveRecord::UnknownAttributeError (unknown attribute: action):
  app/controllers/projects_controller.rb:8:in `create'

我不确定unknown attribute: action 指的是什么。

有关信息,我已将 projects_controller 设置为 resources :projects。我还将rails设置为ActiveRecord::Base.include_root_in_json = false

【问题讨论】:

  • 谢谢,所以 Rails 总是将动作和控制器添加到参数中。这可以解释错误。

标签: ruby-on-rails-3 backbone.js


【解决方案1】:

是的,Rails 总是将actioncontroller 添加到params。参数来自 ActionDispatch::Http::Parameters:

def parameters
  @env["action_dispatch.request.parameters"] ||= begin
    params = request_parameters.merge(query_parameters)
    params.merge!(path_parameters)
    encode_params(params).with_indifferent_access
  end
end

还有path_parameters:

返回带有用于形成请求路径的参数的哈希值。返回的哈希键是字符串:

{'action' => 'my_action', 'controller' => 'my_controller'}

所以你不应该这样做project = Project.create! params。你可以走update_attributes 路线:

project = Project.new
project.update_attributes params[:model_name]

但这假设您在params 的子哈希中拥有您需要的东西,并且它不会调用您的验证器。默认情况下,Backbone 不会命名您的属性,但您可以覆盖 Backbone.sync 并自己做。不过,您可能需要验证,因此通常应避免使用 update_attributes

您最好的选择是从params 中准确提取您期望存在的属性。这甚至是Backbone recommended practise

*(在实际代码中,切勿盲目使用update_attributes,始终将允许更改的属性列入白名单。)*

【讨论】:

  • 是的,感谢您的解释。这似乎让使用 Backbone.js 开始感觉很笨拙,不得不只提取我期望的参数成为维护问题。
  • @shakerlxxv:如果您不希望控制器控制自己的界面,您可以轻松过滤params;你可以dupdelete 摆脱你不想要的东西,或者slice 得到你所期望的东西。当然,在这种情况下,您的模型验证必须非常详细和偏执。
  • 忘了说,update_attributes 方法对我不起作用,仍然产生了 UnknownAttributeError
  • @shakerlxxv:看起来update_attributes 几乎假设你会update_attributes params[:stuff] 并且太笨了,不能只寻找应该在那里的东西。我从不使用它,因为我喜欢拥有清晰和指定的界面,我对它如此简单的想法有点失望。大概 moose56 走的是“从你期望在那里的参数中准确提取属性”的路线,我会为后代更新答案。
  • 我的第一步是使用@mu-is-too-short 提供的信息,通过从哈希中删除操作和控制器参数,以最简单的方式让它工作。一旦一切正常并且我对正在发生的事情有了更好的了解,我对其进行了更新以仅提取我需要的参数。
【解决方案2】:

您可以启用参数包装。在初始化器目录中添加一个文件:

ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json]
end

并且,对于 json 请求,您发布的参数现在将使用模型名称进行包装。

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 2014-02-15
    • 2023-03-14
    • 2022-12-21
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    • 2013-05-27
    • 2017-04-12
    相关资源
    最近更新 更多