Rails基于视图保存后重定向路径

时间:2014-04-18 02:53:22

标签: ruby-on-rails ruby ruby-on-rails-4

我目前在new.html.erb中使用相同的创建和更新方法有两个视图(retirement_accounts_new.html.erbAccounts)。

以下是他们在控制器中定义的方式:

  # GET /accounts/new
  def new
    @account = current_user.accounts.build
  end

  # GET /retirement/accounts/new
  def retirement_accounts_new
    @account = current_user.accounts.build
  end

这是他们共享的相同创建方法:

  def create
    @account = current_user.accounts.build(account_params)
    if @account.save
      redirect_to accounts_path, notice: 'Account was successfully created.'
    else
      render action: 'new'
    end
  end

有没有办法根据哪个视图呈现表单来使redirect_to accounts_path条件化?

我希望retirement_accounts_new保存/更新为redirect_to retirement_accounts

2 个答案:

答案 0 :(得分:0)

听起来这可能是一个设计问题。 AccountsRetirementAccounts有显着差异吗?他们会分享很多相同的逻辑,但不是全部吗?如果是这样,我想我会避免在控制器中使用条件逻辑并使用继承来解决它。

这里的想法是retirement_accounts将被视为路线文件中的新资源:

resources :retirement_accounts

然后为其手动创建一个新控制器(跳过rails generate...命令)。将此文件另存为app/controllers/retirement_accounts_controller.rb

class RetirementAccountsController < AccountsController
end

请注意它是如何从AccountsController而不是ApplicationController继承的。即使在此空状态下,RetirementAccountsController也会共享AccountsController的所有逻辑,包括newcreate方法,以及它们引用的所有视图文件。要对退休帐户进行必要的修改,您只需要覆盖相应的操作和视图。

您可以删除retirement_accounts_new操作,因为它与new操作相同。将retirement_accounts_new的视图移至app/views/retirement_accounts/new.html.erb,以便在new上调用RetirementAccountsController时呈现该模板。

对于条件创建方法,您可以在两个控制器上创建一个私有方法,以确定创建后重定向应指向的位置:

class AccountsController < ApplicationController
  # ...

  def create
    @account = current_user.accounts.build(account_params)
    if @account.save
      redirect_to post_create_redirect_path, notice: 'Account was successfully created.'
    else
      render action: 'new'
    end
  end

  private

  def post_create_redirect_path
    accounts_path
  end
end

class RetirementAccountsController < AccountsController

  private

  def post_create_redirect_path
     retirement_accounts_path
  end
end

答案 1 :(得分:0)

如果RetirementAccount < Account作为单个表继承模型,则默认情况下会发生您要求的事情,

计划B将在重定向中使用显式url_for,例如:

redirect_to url_for(controller: params[:controller], action: :show, id: @account.id), notice: 'Account was successfully created.'

看看api doc,这也应该有效:

redirect_to :action => "show", :id => @account.id,notice: 'Account was successfully created.'

查看http://apidock.com/rails/ActionController/Base/redirect_to - 在某处可能有一个答案:)


PS我假设退休帐户和帐户操作位于不同的控制器中。如果他们不是在不同的控制器而不是不同的模型类别,那么你可以在new形式中放置一个隐藏的标签 - 但这很糟糕&丑陋

最佳解决方案可能是STI模型和2个类别的2个独立资源,一切都将开箱即用。如果这不是一个选项,至少将控制器分开并以这种方式清理,那么重用视图然后重用控制器会好得多