2013-02-27 53 views
1

我知道我無法POST HTML重定向,但是我的情況要求重定向以在對用戶進行身份驗證之後創建操作。我想知道如何繞過這個限制:如何重定向以創建另一個控制器的動作

特別是,我想允許用戶填寫一篇文章,而不使用Omniauth登錄。我使用AJAX調用將帖子保存到會話[:post]。然後,用戶可以使用omniauth登錄並堅持該帖子。

我有創建處理初始AJAX調用行動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 

但是,這不起作用,因爲我無法重定向到「創建」操作。我怎樣才能完成這項任務?

+0

,我認爲是被'渲染動作=>:create',但我struggeling找到文檔吧。 – Automatico 2013-02-27 20:49:10

+0

@ Cort3z:如果你能找到答案,我將不勝感激。我也會去找的。 – AdamNYC 2013-02-27 20:51:46

+1

您應該創建一個答案,而不是編輯您的問題,對未來的訪問者來說它會更具可讀性。看看下面的網址關於如何添加一個沒有錯誤的persist路由(在你的情況下使用集合路由):http://guides.rubyonrails.org/routing.html#adding-more-restful-actions – Baldrick 2013-02-27 21:15:36

回答

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 
+0

感謝您指出錯誤。但是,我得到的錯誤消息是由於我無法重定向來創建操作,因爲它是POST。我從來沒有改變#html的請求:) – AdamNYC 2013-02-27 20:50:17

1

您可以在Post模型上創建一個方法,並從Pos中調用它tsController和ServicesController來保存這篇文章(儘管在這種情況下它很簡單:新建,然後保存,所以在DRY方面你什麼都沒有做到,可能是一些封裝優勢)。或者用所有邏輯創建一個包含create_post方法的公共mixin。然後將其包含到SessionsController和PostsController中,並從'create'中調用它。

在混入模塊:

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 

我沒有編譯和嘗試,所以我只希望它的工作原理。總的來說,我必須說有一些基本錯誤的東西,所以我會尋找其他架構解決方案來獲得相同的結果,但作爲一種快速而又髒的方法,它應該可能起作用。

+1

@ Cort3z我不是在顯示視圖你可以通過渲染做什麼(渲染「帖子/新」,因爲我相信這裏「帖子/創建「是一個POST請求,並沒有一個視圖),但實際上創建帖子(它只存儲在會話中,最初不是在format.json塊中的數據庫中創建的)。所以,渲染不是你需要的。 redirect_to,不能重定向到POST請求,所以你最終會在你的體系結構上做些什麼來達到同樣的結果。 – moonfly 2013-02-27 21:01:03

+0

感謝您的回答。創建一個模塊來在兩個控制器之間共享一個方法對我來說是一個新的學習。但是,這可能表明這裏有些根本錯誤:)。我想出了另一種解決方案,可以避免從兩個控制器中調用方法,例如您建議的第一種方法(請參閱我的更新)。 – AdamNYC 2013-02-27 21:05:00

1

我發現一個黑客來避免這個問題:我讓#創建處理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 

然後我路線。RB,我有:

resources :posts do 
    collection do 
     get 'persist' 
    end 
    end 

最後,在我的ServicesController:

sign_in(:user, service.user) 
redirect_to persist_posts_path 
相關問題