我遇到一个神秘的问题,控制器接收我的ajax请求但没有将其保存在数据库中。在我的服务器日志中,我看到:
Started POST "/collection_maps" for 127.0.0.1 at 2014-07-07 07:14:04 -0600
Processing by CollectionMapsController#create as */*
Parameters: {"collection_id"=>"2", "manufacturer_id"=>"1", "package_id"=>"14"}
(0.1ms) begin transaction
(0.1ms) rollback transaction
Rendered collection_maps/create.js.erb (1.9ms)
Completed 200 OK in 19.2ms (Views: 4.8ms | ActiveRecord: 0.2ms)
127.0.0.1 - - [07/Jul/2014 07:14:04] "POST /collection_maps HTTP/1.1" 200 - 0.0627
我在create.js.erb文件中在浏览器中收到的响应表明参数为空 - 但正如您在上面所看到的那样,它们显然在那里。 (响应仅以文本形式出现,浏览器不会执行代码,但这是另一个问题。我认为。)
// Create a list of errors
var errors = $('<ul />');
errors.append('<li>Package can\'t be blank</li>');
errors.append('<li>Manufacturer can\'t be blank</li>');
errors.append('<li>Collection can\'t be blank</li>');
// Display errors on form
$("#collection-response").html(errors).show();
当我尝试在控制台中创建记录时,使用相同的参数,它可以工作:
irb(main):006:0> c = CollectionMap.new("collection_id"=>"2", "manufacturer_id"=>"1", "package_id"=>"12")
=> #<CollectionMap id: nil, package_id: 12, manufacturer_id: 1, collection_id: 2, created_at: nil, updated_at: nil>
irb(main):007:0> c.save
(0.1ms) begin transaction
SQL (5.7ms) INSERT INTO "collection_maps" ("collection_id", "created_at", "package_id", "manufacturer_id", "updated_at") VALUES (?, ?, ?, ?, ?) [["collection_id", 2], ["created_at", Mon, 07 Jul 2014 06:38:47 UTC +00:00], ["package_id", 12], ["manufacturer_id", 1], ["updated_at", Mon, 07 Jul 2014 06:38:47 UTC +00:00]]
(1.2ms) commit transaction
=> true
irb(main):008:0> c
=> #<CollectionMap id: 6, package_id: 12, manufacturer_id: 1, collection_id: 2, created_at: "2014-07-07 06:38:47", updated_at: "2014-07-07 06:38:47">
我想也许它与CRSF保护有关(虽然我没有用户会话)所以我添加了skip_filter
。这是我的控制器代码:
class CollectionMapsController < ApplicationController
respond_to :js, :html
skip_before_filter :verify_authenticity_token
# POST /collection_maps
# POST /collection_maps.xml
def create
@collection_map = CollectionMap.new(params[:collection_map])
flash[:notice] = "Collection map successfully added" if @collection_map.save
respond_with( @collection_map, :layout => !request.xhr?)
end
这是我的ajax代码:
$.ajax({ url: '<%="#{collection_maps_path}"%>',
type: 'POST',
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token',
'<%="#{form_authenticity_token}"%>')},
dataType: "js",
data: {'collection_id' : this.value,
'manufacturer_id' : $("#remedy_manufacturer_id option:selected").val(),
'package_id' : $("#remedy_package_id option:selected").val()},
});
最后,我的模特:
class CollectionMap < ActiveRecord::Base
belongs_to :manufacturer
belongs_to :package
belongs_to :collection
validates_presence_of :package_id, :manufacturer_id, :collection_id
attr_protected :created_at
attr_protected :updated_at
attr_accessible :package_id, :manufacturer_id, :collection_id
end
我感到非常困惑,所以非常感谢帮助。
更新:我的浏览器没有执行控制器返回的javascript的原因是因为我在ajax请求中有dataType: "js"
。应该是dataType: "script"
。剪切和粘贴的地方要小心!
答案 0 :(得分:2)
您的AJAX请求正在发回您需要的三个参数,但您的控制器操作正在寻找嵌套在:collection_map
键下方的参数。您可以将控制器更改为:
def create
@collection_map = CollectionMap.new(params)
flash[:notice] = "Collection map successfully added" if @collection_map.save
respond_with( @collection_map, :layout => !request.xhr?)
end
或者将您的AJAX请求更改为:
$.ajax({ url: '<%="#{collection_maps_path}"%>',
type: 'POST',
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token',
'<%="#{form_authenticity_token}"%>')},
dataType: "js",
data: {'collection_map': {'collection_id' : this.value,
'manufacturer_id' : $("#remedy_manufacturer_id option:selected").val(),
'package_id' : $("#remedy_package_id option:selected").val()}},
});
更改AJAX请求可能更可取;将参数嵌套在单个键下方更多&#34; Rails-like&#34; / idiomatic。
答案 1 :(得分:1)
您还在混合attr_accessible
和attr_protected
。选一个。或者,如果这是一个较新的Rails(4.0 +)项目,请使用新的params方法,在CollectioMapsController
中为'protection'创建一个类似'collection_map_params'的方法。