javascript - Rails 表单和对不同 Controller 的自定义 Ajax 调用

标签 javascript jquery ruby-on-rails ajax ruby-on-rails-4

我有 3 个模型, channel ,标签,然后是 channel 标签,它们有一个有很多直通关系,设置如下:

channel 模型

has_many :tags, :through => :channel_tags, :dependent => :destroy
has_many :channel_tags, :dependent => :destroy

标签模型

has_many :channel_tags, :dependent => :destroy
has_many :channels, :through => :channel_tags, :dependent => :destroy

channel 标签模型

belongs_to :channel
belongs_to :tag

在我的编辑 channel 表单上,我有一个文本输入,供用户输入标签,然后有一个自定义 js 插件,该插件对数据库进行 ajax 调用,以检查与搜索匹配的现有标签(如果未找到结果),用户可以将搜索词添加为新标签,这是任何博客平台的经典功能。但是,我在添加新标签时遇到一些问题。我有以下 JS 来发帖:

var name = _ts.$input.val(),
    auth_token = $('input[name="authenticity_token"]').val();

$.post('/tags/?&authenticity_token=' + auth_token, { name : name }, function(data) {
     console.log(data);
});

当我第一次这样做时,我收到错误消息,它是一个无效的authenticity_token,我假设这是因为代码用于编辑 channel 表单而不是新标签表单。我读到了将以下内容添加到标签 Controller 的建议:

protect_from_forgery with: :null_session

虽然我不确定它是最好的解决方案,但它有效吗?

但现在我收到 400 错误:

ActionController::ParameterMissing in TagsController#create

param is missing or the value is empty: tag

我非常有信心这是因为我的标签 Controller 中存在以下内容:

 def tag_params
    params.require(:tag).permit(:name,
                                :slug
    )
  end

但是我不确定如何解决这个问题?有没有一种特殊的方法可以用自定义JS与rails交互?我已阅读有关将 form_for 与远程一起使用的文档,但这不适用于我想要做的事情。

任何建议或指导将不胜感激!!

非常感谢 大卫

最佳答案

首先,您应该从 meta 标记(来自 header )获取真实性 token ,而不是从隐藏输入中获取,因为 token 始终存在于 header 中。然后您应该设置 AJAX 调用,以便 X-CSRF-Token header 将与您的所有请求一起发送:

$.ajaxSetup({
  beforeSend: function(xhr) {
    var token = $('meta[name="csrftoken"]').attr('content');
    xhr.setRequestHeader('X-CSRF-Token', token);
  }
}); 

现在您可以保留原来的protect_from_forgery方法。我认为在这里使用 protect_from_forgery with: :null_session 不是一个好主意。然后您应该实现其他授权机制。

至于您的参数,根据请求:

$.post('/tags', { name : name }, function(data) {
  console.log(data);
});

TagsController#create 接收的参数将为 {name: 'tag name'}。所以 params.require(:tag) 肯定会丢失。你应该使用;而是使用 params.permit(:name) 。但是,我认为,最好还是遵循 Rails 默认值并更改 AJAX 调用:

$.post('/tags', { tag: { name : name } }, function(data) {
  console.log(data);
});

关于javascript - Rails 表单和对不同 Controller 的自定义 Ajax 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32638514/

相关文章:

javascript - chrome 扩展检测 ERR_PROXY_CONNECTION_FAILED

jquery - 创建新的 CsQuery 对象而不继承

ruby-on-rails - rails : validate unique friendship relationships

ruby-on-rails - 指定要从 before_filter 中排除的 Controller

javascript - 如何将数据 block 发送到 AWS

javascript - 在 Javascript 中减去日期也减去月份

php echo 返回失败给 jQuery

javascript - Angularjs - 如何绑定(bind)到由 javascript 代码附加的 html 元素

javascript - 如何使用请求 header 之一的值在 Postman 中设置全局变量?

mysql - 在 32 位 Rails 应用程序上将 32 位 PK 更改为 BIGINT