1

HTML リダイレクトで POST できないことは理解していますが、私の状況では、ユーザーの認証後にアクションを作成するためにリダイレクトする必要があります。この制限を回避する方法を知りたい:

特に、ユーザーが Omniauth を使用してログインせずに投稿に記入できるようにしたいと考えています。AJAX 呼び出しを使用して、投稿を session[:post] に保存します。次に、ユーザーは omniauth を使用してログインし、投稿を永続化できます。

最初の ajax 呼び出しを処理する create アクションを備えた PostsController があり、ユーザー認証後に 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

ただし、「作成」アクションにリダイレクトできないため、これは機能しません。どうすればこのタスクを達成できますか?

4

3 に答える 3

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
于 2013-02-27T20:45:33.310 に答える
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
于 2013-02-27T21:28:54.627 に答える
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

コンパイルして試していないので、うまくいくことを願っています。一般的に、何か根本的に間違っていると言わざるを得ないので、同じ結果を達成するために他のアーキテクチャ ソリューションを探しますが、簡単で汚いアプローチとしては、おそらくうまくいくはずです。

于 2013-02-27T20:53:08.463 に答える