模型保存失败时如何保持rails嵌套资源路由URL?

时间:2016-11-30 18:51:55

标签: ruby-on-rails

要点:

我有一个嵌套属性。我去路线:

/customers/:id/credit_cards/new

在创建操作上,保存失败,代码执行

render :new 

这会将URL推送到:

/credit_cards/new

如何确保网址与客户路线保持一致?

详细信息:

我想使用以下路线:

# Credit cards should be associated with a customer except
# potentially on initial creation:
resources :customers do
  resources :credit_cards, only: [:index, :show, :new, :create, :edit, :update, :destroy, :show]
end
# Allow creating a credit card but selecting
resources :credit_cards, only: [:new, :create]

基本上是客户存在时的嵌套路由,以及我可以在同一视图中创建和分配客户的非嵌套路由。

我在

有一个控制器
app/controller/credit_cards_controller.rb

在新的和创建操作中,我检查是否有客户ID

before_action :set_credit_card, only: [:show, :edit, :update, :destroy]
before_action :set_customer, only: [:index, :show, :create, :new, :edit, :update]

# GET /credit_cards/new                                                                                                                                  
def new
  @credit_card = if @customer
                   @customer.credit_cards.build rescue CreditCard.new
                 else
                   CreditCard.new
                 end
end

def create
  @credit_card = CreditCard.new(credit_card_params)
  respond_to do |format|
    if @credit_card &&  @credit_card.save
      format.html { redirect_to on_new_or_update_redirect_location, notice: 'Credit card was successfully created.' }
    else
      # HERE IS THE ISSUE: Figure out how to make sure the url stays as /customers/:id/credit_cards/new instead of /credit_cards/new                                                                 
      format.html { render :new }
    end
  end
end

如果验证失败,它会重新呈现视图,但会将URL推送到

credit_cards/new

所以我不再使用正确的URL,而customer_id不再是参数。我假设如果我可以通过customer_id它将做正确的事情,但我还没有找到如何做到这一点。

1 个答案:

答案 0 :(得分:1)

这可能是因为您的表单发布到/credit_cards而不是/customers/:id/credit_cards

将表单更改为以下内容:

<%= form_for [@customer, @credit_card] do -%>
  ... etc...
<%= end %>

这应该处理任何一种情况 - @customer是否被定义。如果定义了客户,它将发布到customer_credit_cards_path(@customer),如果未定义客户,则发布到credit_card_path。请务必在@customer操作中设置create变量。这样当你render :new时,它将使用@customer变量呈现表单。