Javascript Rails表单和对不同控制器的自定义Ajax调用
我有3个模型,频道,标签,然后是频道标签,它们有一个多通关系,设置如下: 渠道模式Javascript Rails表单和对不同控制器的自定义Ajax调用,javascript,jquery,ruby-on-rails,ajax,ruby-on-rails-4,Javascript,Jquery,Ruby On Rails,Ajax,Ruby On Rails 4,我有3个模型,频道,标签,然后是频道标签,它们有一个多通关系,设置如下: 渠道模式 has_many :tags, :through => :channel_tags, :dependent => :destroy has_many :channel_tags, :dependent => :destroy has_many :channel_tags, :dependent => :destroy has_many :channels, :through =>
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
belongs_to :channel
belongs_to :tag
标签型号
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
belongs_to :channel
belongs_to :tag
频道标签型号
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
belongs_to :channel
belongs_to :tag
在我的编辑频道表单上,我有一个文本输入,用户可以输入一个标签,然后是一个自定义的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);
});
当我第一次这样做的时候,我得到的错误是它是一个无效的Authentity_令牌,我假设这是因为代码是用于编辑频道表单而不是新的标记表单。我阅读了一条建议,将以下内容添加到标记控制器:
protect_from_forgery with: :null_session
def tag_params
params.require(:tag).permit(:name,
:slug
)
end
虽然我不确定这是不是最好的解决方案,但这确实奏效了
但现在我得到一个400错误,说:
ActionController::ParameterMissing in TagsController#create
param is missing or the value is empty: tag
我很有信心这是因为我的标签控制器中有以下内容:
protect_from_forgery with: :null_session
def tag_params
params.require(:tag).permit(:name,
:slug
)
end
然而,我不确定如何解决这个问题?有没有一种特殊的方法可以使用自定义JS与rails交互?我已经阅读了有关使用表单_for with remote的文档,但这不适用于我正在尝试的操作
任何建议或指导都将不胜感激
非常感谢
David首先,您应该从
meta
标记(从标题)获取您的真实性令牌,而不是从隐藏输入获取,因为令牌始终存在于标题中。然后您应该设置AJAX调用,以便X-CSRF-Token
头将与您的所有请求一起发送:
$.ajaxSetup({
beforeSend: function(xhr) {
var token = $('meta[name="csrftoken"]').attr('content');
xhr.setRequestHeader('X-CSRF-Token', token);
}
});
现在您可以保留原始保护您免受伪造方法。我认为在这里使用通过::null\u session
防止伪造不是一个好主意。然后,您应该实现其他授权机制
关于您的参数,根据请求:
$.post('/tags', { name : name }, function(data) {
console.log(data);
});
TagsController#create
接收的参数将是{name:'tagname'}
。因此,params.require(:tag)
肯定会丢失。你应该使用<代码>参数许可证(:名称)
。但是,我认为,最好还是遵循Rails的默认设置,改为更改AJAX调用:
$.post('/tags', { tag: { name : name } }, function(data) {
console.log(data);
});
首先,您应该从meta
标记(从标题)获取您的真实性令牌,而不是从隐藏输入获取,因为令牌始终存在于标题中。然后您应该设置AJAX调用,以便X-CSRF-Token
头将与您的所有请求一起发送:
$.ajaxSetup({
beforeSend: function(xhr) {
var token = $('meta[name="csrftoken"]').attr('content');
xhr.setRequestHeader('X-CSRF-Token', token);
}
});
现在您可以保留原始保护您免受伪造方法。我认为在这里使用通过::null\u session
防止伪造不是一个好主意。然后,您应该实现其他授权机制
关于您的参数,根据请求:
$.post('/tags', { name : name }, function(data) {
console.log(data);
});
TagsController#create
接收的参数将是{name:'tagname'}
。因此,params.require(:tag)
肯定会丢失。你应该使用<代码>参数许可证(:名称)
。但是,我认为,最好还是遵循Rails的默认设置,改为更改AJAX调用:
$.post('/tags', { tag: { name : name } }, function(data) {
console.log(data);
});
你是我的英雄!!这正是我想要的!!这一切都很有道理,我自己并不觉得空会话方法是最好的,所以我真的很高兴不用担心这一点。唯一很小的调整是csrftoken的jquery选择器应该是带有连字符的“meta[name=“csrf token”]”。再次感谢!!当你的应用程序中有其他身份验证机制(例如OAuth)时,空会话是一个很好的方法。你是我的英雄!!这正是我想要的!!这一切都很有道理,我自己并不觉得空会话方法是最好的,所以我真的很高兴不用担心这一点。唯一很小的调整是csrftoken的jquery选择器应该是带有连字符的“meta[name=“csrf token”]”。再次感谢!!当应用程序中有其他身份验证机制(例如OAuth)时,null_会话是一种很好的方法。