Rails 5: AJAX 未触发 save/load 回调 (PATCH / GET)
Rails 5: AJAX not triggering for save/load callbacks (PATCH / GET)
我有点难以实现 AJAX 和 JSON 响应。我有这个 控制器
class Common::DatatablesStatesController < ApplicationController
def update
datatables_state.update(datatable_states_params)
render json: datatables_state
end
def show
render json: datatables_state
end
private
def datatable_states_params
params.require(:common_datatable_state).permit(:user_id, :name, :state)
end
def datatables_state
@datatables_state ||= current_user.datatables_states
.where(name: params[:id]).first_or_create
end
end
基本上检查参数记录是否存在,如果存在,则更新 state
列,如果不存在 - 创建新记录(current_user ID,下面 JS 的 contname,状态)
我的 Coffeescript 目前看起来像这样:
$ ->
$('#data-table').DataTable
ajax: $('#data-table').data('source')
serverSide: true
stateSave: true
contname = $('#data-table').attr('data-controller-name')
'stateSaveCallback': (settings, data) ->
$.ajax
'url': '/common/datatables_states/' + contname + '.json'
'data':
'user_id': user_id
'name': contname
'state': data
'dataType': 'json'
'type': 'PATCH'
success: ->
return
'stateLoadCallback': (settings, callback) ->
$.ajax
'url': '/common/datatables_states/' + contname + '.json'
'data':
'name': contname
'state': data
'async': false
'dataType': 'json'
'type': 'GET'
'success': (json) ->
callback json
return
return
return
我很确定我的 JS 部分有问题,因为我的控制台没有发生任何事情,但我不知道它是什么。我很乐意提供任何帮助。谢谢!
更新
我的路线是这样的:
namespace :common do
resources :datatables_states, only: [:update, :show]
end
rails routes
common_datatables_state GET (/:locale)/common/datatables_states/:id(.:format) common/datatables_states#show {:locale=>/en|lv/}
PATCH (/:locale)/common/datatables_states/:id(.:format) common/datatables_states#update {:locale=>/en|lv/}
PUT (/:locale)/common/datatables_states/:id(.:format) common/datatables_states#update {:locale=>/en|lv/}
基本上想法是将 data-controller-name
作为 ID 从视图中传递。
更新2
我转而使用 vanila JS,因为我怀疑我的 Coffeescript 有问题。这是我放入 JS 文件的内容:
jQuery(document).ready(function() {
$('#data-table').DataTable(
{
"processing": true,
"serverSide": true,
"ajax": $('#data-table').data('source'),
stateSave: true,
"stateSaveCallback": function (settings, data) {
// Send an Ajax request to the server with the state object
$.ajax( {
"url": "/common/datatables_states/campaigns_index.json", //Test link with :ID campaigns_index.json
"data": {"name":"campaigns_index", "state": data} ,
"dataType": "json",
"type": "PATCH",
"success": function () {}
} );
},
stateLoadCallback: function (settings, callback) {
$.ajax( {
url: '/common/datatables_states/campaigns_index.json',
async: false,
dataType: 'json',
type: 'GET',
success: function (json) {
callback( json );
}
} );
}
}
);
});
这就是我现在在控制台中看到的内容:
Started PATCH "/common/datatables_states/campaigns_index.json" for 10.0.2.2 at 2017-05-12 20:27:03 +0000
Processing by Common::DatatablesStatesController#update as JSON
Parameters: {"name"=>"campaigns_index", "state"=>{"time"=>"1494620823501", "start"=>"0", "length"=>"10", "order"=>{"0"=>["0", "asc"]}, "search"=>{"search"=>"", "smart"=>"true", "regex"=>"false", "caseInsensitive"=>"true"}, "columns"=>{"0"=>{"visible"=>"true", "search"=>{"search"=>"", "smart"=>"true", "regex"=>"false", "caseInsensitive"=>"true"}}, "1"=>{"visible"=>"true", "search"=>{"search"=>"", "smart"=>"true", "regex"=>"false", "caseInsensitive"=>"true"}}, "2"=>{"visible"=>"true", "search"=>{"search"=>"", "smart"=>"true", "regex"=>"false", "caseInsensitive"=>"true"}}}}, "id"=>"campaigns_index"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 2], ["LIMIT", 1]]
Common::DatatableState Load (1.5ms) SELECT "common_datatable_states".* FROM "common_datatable_states" WHERE "common_datatable_states"."user_id" = AND "common_datatable_states"."name" = ORDER BY "common_datatable_states"."id" ASC LIMIT [["user_id", 2], ["name", "campaigns_index"], ["LIMIT", 1]]
Completed 400 Bad Request in 15ms (ActiveRecord: 2.0ms)
ActionController::ParameterMissing (param is missing or the value is empty: common_datatable_state):
app/controllers/common/datatables_states_controller.rb:14:in `datatable_states_params'
app/controllers/common/datatables_states_controller.rb:4:in `update'
app/controllers/application_controller.rb:45:in `set_current_user'
更新 3
我正在尝试为我的 DataTables 1.10.13 实施 stateLoadCallback。
我将我的控制器操作更改为此,因此它仅选择 state
:
def show
state = current_user.datatables_states.where(name: params[:id]).select(:state)
render json: state
end
然后在 JS 中我这样做,这是根据文档:
stateLoadCallback: function (settings, callback) {
$.ajax( {
url: '/common/datatables_states/campaigns_index.json',
async: false,
dataType: 'json',
type: 'GET',
success: function (json) {
callback( json );
}
} );
}
但是在终端我没有得到 state
返回:
Started GET "/common/datatables_states/campaigns_index.json" for 10.0.2.2 at 2017-05-14 10:02:03 +0000
Processing by Common::DatatablesStatesController#show as JSON
Parameters: {"id"=>"campaigns_index"}
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 2], ["LIMIT", 1]]
Common::DatatableState Load (1.6ms) SELECT "common_datatable_states"."state" FROM "common_datatable_states" WHERE "common_datatable_states"."user_id" = AND "common_datatable_states"."name" = [["user_id", 2], ["name", "campaigns_index"]]
Completed 200 OK in 83ms (Views: 25.3ms | ActiveRecord: 9.6ms)
我的 state
列的类型是 JSON,当我导航到 http://localhost:3000/en/common/datatables_states/campaigns_index.json
时,我看到了这个:
[
{
"id": null,
"state": "{\"time\":\"1494761473541\",\"start\":\"0\",\"length\":\"10\",\"order\":{\"0\":[\"0\",\"asc\"]},\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"},\"columns\":{\"0\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"1\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"2\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}}}}"
}
]
更新 3.1.
我加了state = current_user.datatables_states.where(name: params[:id]).select(:state).first
我现在有这个:
{
"id": null,
"state": "{\"time\":\"1494910215056\",\"start\":\"0\",\"length\":\"10\",\"order\":{\"0\":[\"0\",\"asc\"]},\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"},\"columns\":{\"0\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"1\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"2\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}}}}"
}
当我将 show
更改为:
def show
state = current_user.datatables_states.where(name: params[:id]).select(:state).first
my_hash = JSON.parse(state)
render json: JSON.pretty_generate(my_hash)
end
并得到这个错误:
TypeError (no implicit conversion of nil into String):
app/controllers/common/datatables_states_controller.rb:10:in `show'
app/controllers/application_controller.rb:45:in `set_current_user'
我应该怎么做才能使我的 stateLoadCallback 工作?
我认为问题出在这里 where(name: params[:id])
,你能检查这里的参数吗
您添加的错误表明没有传递 common_datatable_state
参数,这是因为您如何定义强参数(datatable_state_params
方法)。尝试像这样更改 ajax 调用中的 data
字段:
"data": {"common_datatable_state":{"name":"campaigns_index", "state": data}}
我有点难以实现 AJAX 和 JSON 响应。我有这个 控制器
class Common::DatatablesStatesController < ApplicationController
def update
datatables_state.update(datatable_states_params)
render json: datatables_state
end
def show
render json: datatables_state
end
private
def datatable_states_params
params.require(:common_datatable_state).permit(:user_id, :name, :state)
end
def datatables_state
@datatables_state ||= current_user.datatables_states
.where(name: params[:id]).first_or_create
end
end
基本上检查参数记录是否存在,如果存在,则更新 state
列,如果不存在 - 创建新记录(current_user ID,下面 JS 的 contname,状态)
我的 Coffeescript 目前看起来像这样:
$ ->
$('#data-table').DataTable
ajax: $('#data-table').data('source')
serverSide: true
stateSave: true
contname = $('#data-table').attr('data-controller-name')
'stateSaveCallback': (settings, data) ->
$.ajax
'url': '/common/datatables_states/' + contname + '.json'
'data':
'user_id': user_id
'name': contname
'state': data
'dataType': 'json'
'type': 'PATCH'
success: ->
return
'stateLoadCallback': (settings, callback) ->
$.ajax
'url': '/common/datatables_states/' + contname + '.json'
'data':
'name': contname
'state': data
'async': false
'dataType': 'json'
'type': 'GET'
'success': (json) ->
callback json
return
return
return
我很确定我的 JS 部分有问题,因为我的控制台没有发生任何事情,但我不知道它是什么。我很乐意提供任何帮助。谢谢!
更新
我的路线是这样的:
namespace :common do
resources :datatables_states, only: [:update, :show]
end
rails routes
common_datatables_state GET (/:locale)/common/datatables_states/:id(.:format) common/datatables_states#show {:locale=>/en|lv/}
PATCH (/:locale)/common/datatables_states/:id(.:format) common/datatables_states#update {:locale=>/en|lv/}
PUT (/:locale)/common/datatables_states/:id(.:format) common/datatables_states#update {:locale=>/en|lv/}
基本上想法是将 data-controller-name
作为 ID 从视图中传递。
更新2
我转而使用 vanila JS,因为我怀疑我的 Coffeescript 有问题。这是我放入 JS 文件的内容:
jQuery(document).ready(function() {
$('#data-table').DataTable(
{
"processing": true,
"serverSide": true,
"ajax": $('#data-table').data('source'),
stateSave: true,
"stateSaveCallback": function (settings, data) {
// Send an Ajax request to the server with the state object
$.ajax( {
"url": "/common/datatables_states/campaigns_index.json", //Test link with :ID campaigns_index.json
"data": {"name":"campaigns_index", "state": data} ,
"dataType": "json",
"type": "PATCH",
"success": function () {}
} );
},
stateLoadCallback: function (settings, callback) {
$.ajax( {
url: '/common/datatables_states/campaigns_index.json',
async: false,
dataType: 'json',
type: 'GET',
success: function (json) {
callback( json );
}
} );
}
}
);
});
这就是我现在在控制台中看到的内容:
Started PATCH "/common/datatables_states/campaigns_index.json" for 10.0.2.2 at 2017-05-12 20:27:03 +0000
Processing by Common::DatatablesStatesController#update as JSON
Parameters: {"name"=>"campaigns_index", "state"=>{"time"=>"1494620823501", "start"=>"0", "length"=>"10", "order"=>{"0"=>["0", "asc"]}, "search"=>{"search"=>"", "smart"=>"true", "regex"=>"false", "caseInsensitive"=>"true"}, "columns"=>{"0"=>{"visible"=>"true", "search"=>{"search"=>"", "smart"=>"true", "regex"=>"false", "caseInsensitive"=>"true"}}, "1"=>{"visible"=>"true", "search"=>{"search"=>"", "smart"=>"true", "regex"=>"false", "caseInsensitive"=>"true"}}, "2"=>{"visible"=>"true", "search"=>{"search"=>"", "smart"=>"true", "regex"=>"false", "caseInsensitive"=>"true"}}}}, "id"=>"campaigns_index"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 2], ["LIMIT", 1]]
Common::DatatableState Load (1.5ms) SELECT "common_datatable_states".* FROM "common_datatable_states" WHERE "common_datatable_states"."user_id" = AND "common_datatable_states"."name" = ORDER BY "common_datatable_states"."id" ASC LIMIT [["user_id", 2], ["name", "campaigns_index"], ["LIMIT", 1]]
Completed 400 Bad Request in 15ms (ActiveRecord: 2.0ms)
ActionController::ParameterMissing (param is missing or the value is empty: common_datatable_state):
app/controllers/common/datatables_states_controller.rb:14:in `datatable_states_params'
app/controllers/common/datatables_states_controller.rb:4:in `update'
app/controllers/application_controller.rb:45:in `set_current_user'
更新 3
我正在尝试为我的 DataTables 1.10.13 实施 stateLoadCallback。
我将我的控制器操作更改为此,因此它仅选择 state
:
def show
state = current_user.datatables_states.where(name: params[:id]).select(:state)
render json: state
end
然后在 JS 中我这样做,这是根据文档:
stateLoadCallback: function (settings, callback) {
$.ajax( {
url: '/common/datatables_states/campaigns_index.json',
async: false,
dataType: 'json',
type: 'GET',
success: function (json) {
callback( json );
}
} );
}
但是在终端我没有得到 state
返回:
Started GET "/common/datatables_states/campaigns_index.json" for 10.0.2.2 at 2017-05-14 10:02:03 +0000
Processing by Common::DatatablesStatesController#show as JSON
Parameters: {"id"=>"campaigns_index"}
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = LIMIT [["id", 2], ["LIMIT", 1]]
Common::DatatableState Load (1.6ms) SELECT "common_datatable_states"."state" FROM "common_datatable_states" WHERE "common_datatable_states"."user_id" = AND "common_datatable_states"."name" = [["user_id", 2], ["name", "campaigns_index"]]
Completed 200 OK in 83ms (Views: 25.3ms | ActiveRecord: 9.6ms)
我的 state
列的类型是 JSON,当我导航到 http://localhost:3000/en/common/datatables_states/campaigns_index.json
时,我看到了这个:
[
{
"id": null,
"state": "{\"time\":\"1494761473541\",\"start\":\"0\",\"length\":\"10\",\"order\":{\"0\":[\"0\",\"asc\"]},\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"},\"columns\":{\"0\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"1\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"2\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}}}}"
}
]
更新 3.1.
我加了state = current_user.datatables_states.where(name: params[:id]).select(:state).first
我现在有这个:
{
"id": null,
"state": "{\"time\":\"1494910215056\",\"start\":\"0\",\"length\":\"10\",\"order\":{\"0\":[\"0\",\"asc\"]},\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"},\"columns\":{\"0\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"1\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"2\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}}}}"
}
当我将 show
更改为:
def show
state = current_user.datatables_states.where(name: params[:id]).select(:state).first
my_hash = JSON.parse(state)
render json: JSON.pretty_generate(my_hash)
end
并得到这个错误:
TypeError (no implicit conversion of nil into String):
app/controllers/common/datatables_states_controller.rb:10:in `show'
app/controllers/application_controller.rb:45:in `set_current_user'
我应该怎么做才能使我的 stateLoadCallback 工作?
我认为问题出在这里 where(name: params[:id])
,你能检查这里的参数吗
您添加的错误表明没有传递 common_datatable_state
参数,这是因为您如何定义强参数(datatable_state_params
方法)。尝试像这样更改 ajax 调用中的 data
字段:
"data": {"common_datatable_state":{"name":"campaigns_index", "state": data}}