成功的ajax表单后重定向到

时间:2012-04-01 09:33:32

标签: ruby-on-rails ajax ruby-on-rails-3

我有一张带远程=>的表单真正。 现在我的控制器看起来像:

  # POST /items
  # POST /items.json
  def create
    @item = @store.items.build(params[:item])

    respond_to do |format|
      if @item.save
        format.html { redirect_to edit_admin_item_path(@item), :flash => {:success => "#{@item.name} was successfully created."} }
        format.js { render :js => "window.location.href = ('#{edit_admin_item_path(@item)}');"}
        format.json { render json: @item, status: :created, location: @item }
      else
        format.html { render action: "new" }
        format.js { render :partial => 'fail_create.js.erb', :locals => { :ajax_errors => @item.errors.full_messages } }
        format.json { render json: @item.errors, status: :unprocessable_entity }       
      end
    end
  end

哪个有效,但感觉非常笨拙。它也不允许我使用闪光通知,这确实是悲伤的时间。

理想情况下,我觉得我应该能够简单地使用“format.js {redirect_to ...}或检查请求标头和redirect_to。Sheesh!

我不确定最佳解决方案是什么。任何建议都会超级棒,提前谢谢!

- PS - 我知道之前有人问过这个问题,但无济于事:How to redirect after a successful AJAX form submission。似乎有许多相似的问题浮出水面,但没有真正的解决方案。

3 个答案:

答案 0 :(得分:5)

我认为这可能是不可能的。对XML Ajax请求的响应由XMLHttpRequest处理。如果返回3xx响应,则XMLHttpRequest将遵循重定向本身,如果URL具有相同的来源。无论您如何设置标头,浏览器都无法意识到这一点。所以唯一的方法就是用一些Javascript来改变window.location。

答案 1 :(得分:4)

我使用Rails responders的组合来生成我的回复消息以及<action>.js文件中的一些内容。

- update.js的内容看起来像这样:

// Checks if the article slug has changed.
// If it has the entire page should be reloaded at that new location.
<%= reload_if_slug_changed @article, params[:id] %>

// Displays the flash notices
// See ApplicationHelper#js_flash_response
<%= js_flash_response %>

在某个帮助器中定义了不同的方法(在我的例子中是我的ApplicationHelper)。不同方法的内容如下:

def js_flash_response
  if flash.now[:notice].present?
    js = "$('#notice').html('#{flash.now[:notice]}').change();"
  elsif flash.now[:alert].present?
    js = "$('#alert').html('#{flash.now[:alert]}').change();"
  end
end

def reload_if_slug_changed object, expected_value
  "window.location.href = '#{url_for [:edit, object]}';" if object.slug != expected_value
end

Flash消息的内容由Rails responders自动生成,并显示在删除闪存哈希值的now范围内,确保用户重新加载(在显示闪存后)他们不会再出现。

我不相信你应该制作一个指向宁静的create动作的表单,因为你总是期望重要的重定向,所以在我的情况下我只需要重定向如果url slug已经改变了。

我希望这会有所帮助。这不是一个解决方案,而只是我处理一些相同问题的方式。

最好的问候。

答案 2 :(得分:3)

在您的场景中,这是我如何从控制器操作将javascript注入页面。在完成操作的逻辑部分后,插入以下内容:

render :update do |page|
    page << "javascript_here"
end

这应该允许你插入window.location或创建一个javascript flash方法,并在你的create方法正确执行时调用它。

如果您想要阻止控制器操作,我建议您查看this Railscast about make_resourceful。 Make_resourceful自动执行每个操作的每个核心活动。它还允许您点按他们创建的挂钩,例如before :createafter :createresponse_for :createafter :create_fails。通过使用这个gem,您可以根据方法的成功或失败运行代码,并对它们进行更精细的控制。

除此之外,您应该能够在视图文件中初始化create.js.erb和create_fails.js.erb,包含一个format.js,而不会在控制器中传递任何内容,并且Rails将自动运行该文件包含javascript,具体取决于控制器操作是否成功执行。