我知道我无法对HTML重定向进行POST,但我的情况要求我在对用户进行身份验证后重定向以创建操作。我想知道如何绕过这个限制:
特别是,我想允许用户填写帖子而无需使用Omniauth登录。我使用AJAX调用将帖子保存到session [:post]。然后,用户可以使用omniauth登录并保留帖子。
我有一个带有创建操作的PostsController,用于处理初始ajax调用,并在验证用户后处理html请求:
def create
@post = Post.new(params[:post])
respond_to do |format|
format.html{
if @post.save
redirect_to @post, notice: 'Post was successfully created.'
else
render action: "new"
end
}
format.json {
if session[:post] = @post
render json: @post, status: :created, location: @post
else
render json: @post.errors, status: :unprocessable_entity
end
}
end
end
end
然后,在我处理来自Facebook的回调的控制器中,我有:
class ServicesController < ApplicationController
def create
... authentication logic here ...
sign_in(:user, service.user)
redirect_to :controller => "posts", :action =>"create"
end
method_alias: :facebook, :create
但是,这不起作用,因为我无法重定向到“创建”操作。我怎样才能完成这项任务?
答案 0 :(得分:1)
在您发布的代码中,您永远不会阅读会话的内容。我认为如果你改变你的代码它可以工作:
更改@post
的初始化:
@post = Post.new(params[:post]) || session[:post] # Find object in session if not
在post.save
之后添加:
session.delete :post # clean session after successful creation
新的完整方法:
def create
@post = Post.new(params[:post]) || session[:post] # Find object in session if not in params
respond_to do |format|
format.html{
if @post.save
redirect_to @post, notice: 'Post was successfully created.'
session.delete :post # clean session after successful creation
else
render action: "new"
end
}
format.json {
if session[:post] = @post
render json: @post, status: :created, location: @post
else
render json: @post.errors, status: :unprocessable_entity
end
}
end
end
end
答案 1 :(得分:1)
你可以在Post模型上创建一个方法,并从PostsController和ServicesController中调用它来保存帖子(虽然在这种情况下它非常简单:新的,然后保存,所以你在DRY方面没有任何成就,可能是一些封装的好处)。或者使用所有逻辑创建包含create_post方法的公共mixin。然后将其包含在SessionsController和PostsController中,并从“create”调用它。
在mixin模块中:
def create_post(allow_json=false)
@post = Post.new(params[:post])
respond_to do |format|
format.html {
if @post.save
redirect_to @post, notice: 'Post was successfully created.'
else
render "posts/new"
end
}
if allow_json
... your post-saving & json-processing logic ...
end
end
end
在PostsController中:
def create
create_post(true)
end
在SessionsController中:
def create
... authentication logic here ...
sign_in(:user, service.user)
create_post(false)
end
我没有编译和尝试,所以我只希望它有效。总的来说,我必须说有一些基本上是错误的,所以我会寻找其他架构解决方案来实现相同的结果,但作为一种快速而肮脏的方法它应该可行。
答案 2 :(得分:1)
我发现了一个黑客来避免这个问题:我让#create处理AJAX调用并写入会话,然后创建另一个操作以在用户进行身份验证后将其持久保存到我的数据库中:
class PostsController < ApplicationController
def create
@post = Post.new(params[:post])
respond_to do |format|
format.json {
if session[:post] = @post
render json: @post, status: :created, location: @post
else
render json: @post.errors, status: :unprocessable_entity
end
}
end
end
def persist
@post = session[:post]
if @post.save
session.delete :post
redirect_to @post, notice: 'Post was successfully created.'
else
render action: "new"
end
end
然后在我的routes.rb中,我有:
resources :posts do
collection do
get 'persist'
end
end
最后,在我的ServicesController中:
sign_in(:user, service.user)
redirect_to persist_posts_path