在Rails 3当资源创建操作失败,并呼吁渲染,新的,为什么一定要在URL改变资源的指数网址是什么?

2019-07-18 14:54发布

我有一个叫做资源书籍。 它列为我的路线文件中正确的资源。

我有一个新的动作,这给新视图的标准:

@book = Book.new

在模型中,有哪些是由存在验证某些属性,因此,如果保存操作失败,会产生错误。

在我的控制器:

@book = Book.create
...  # some logic
if @book.save
  redirect_to(@book)
else
  render :new
end

这是非常标准的; 以及使用渲染理由:新鲜的是,这样的对象被传递回视图,可报告的错误,表单提交,重新填充等。

这工作,但每次我送回表格时(通过渲染,新的),我的错误出现,但我的网址是索引网址,这是

/books

而不是

/books/new

这是我在第一时间开始了。 我见过几个人张贴关于这个问题,但没有答案。 至少,人们会认为它会降落在你的/书籍/创建,这也是我必须(在这种情况下,等同于新)的视图文件。

我可以做这个:

# if the book isn't saved then
flash[:error] = "Errors!"
redirect_to new_book_path

但随后的@book数据丢失,与所述错误消息一起,它是具有形式和动作等的整个点

为什么会呈现新的/书籍登陆我,我的指标动作,当通常是URL调用Index方法,其中列出了所有的书?

Answer 1:

它实际上送你的创建路径。 这是在create动作,路径是/books ,使用HTTP POST方法。 这看起来一样的索引路径/books ,但该指数路径使用HTTP GET方法。 确定要调用哪个动作时导轨路由代码采用该方法考虑在内。 验证失败后,你仍然在创造动作,但你呈现new视图。 这是一个有点混乱,但像一条线render :new不实际调用新的动作在所有; 它仍然运行创建行动,它告诉Rails来呈现新的视图



Answer 2:

我刚开始使用Rails的教程和有同样的问题。 该解决方案只是简单的:如果你想提交表单(有错误)之后相同的URL,只是结合了新的和一个行动创建行动。

这里是我的代码,这使得这一切成为可能的部分(希望它可以帮助别人^^)

routes.rb中(添加新的动作后路线):

...
    resources :books
    post "books/new"
...

控制器:

...
def create
    @book = Book.new(book_params)

    if @book.save
        # save was successful
        print "Book saved!"

        else
        # If we have errors render the form again   
        render 'new'
    end
end

def new 
    if book_params
        # If data submitted already by the form we call the create method
        create
        return
    end

    @book = Book.new

    render 'new' # call it explicit
end

private

def book_params
    if params[:book].nil?  || params[:book].empty?
        return false
    else
        return params.require(:book).permit(:title, :isbn, :price)
    end
end

new.html.erb:

<%= form_for @book, :url => {:action => :new} do |f| %>
  <%= f.label :title %>
  <%= f.text_field :title %>

  <%= f.label :isbn %>
  <%= f.text_field :isbn %>

  <%= f.label :price %>
  <%= f.password_field :price %>

  <%= f.submit "Save book" %>
<% end %>


Answer 3:

只要有同样的问题,所以也许这可能帮助别人一天。 基本上,你必须做出调整,3,为了这个东西的工作,虽然我的解决方案仍不理想。

1)在创建操作:

if @book.save
  redirect_to(@book)
else
  flash[:book] = @book
  redirect_to new_book_path
end

2)在新的动作:

@book = flash[:book] ? Book.new(flash[:book]): Book.new

3)无论你解析闪光灯散,一定要过滤掉闪光灯[:书]。

- >显示正确的URL,表单数据将被保留。 不过,我有点不喜欢把用户对象到闪存散,我不认为这是它的目的。 是否anyboy知道一个更好的地方,把它?



Answer 4:

它不以土地你/books/new ,因为你被张贴到创建资源/books/ 。 当你创建失败,它只是呈现新的行动,而不是重定向你的新动作。 作为@MrYoshiji说上面你可以尝试重定向到新的行动,但这的确是低效的,因为你会创建另一个HTTP请求和往返于服务器,只改变URL。 在这一点上,如果它很重要,你可能可以使用JavaScript改变它。



Answer 5:

它可以通过使用相同的URL,但新创造的行动不同的方法来固定。

在路由文件可以使用下面的代码。

resources :books do
  get :common_path_string, on: :collection, action: :new
  post :common_path_string, on: :collection, action: :create
end

现在,新的页面将呈现的网址

书籍/ common_path_string

如果任何错误来验证后,仍然将URL相同。

另外在窗体,而不是使用

books_path

使用

url: common_path_string_books_path, method: :post

选择你喜欢的common_path_string。



文章来源: In Rails 3, when a resource create action fails and calls render :new, why must the URL change to the resource's index url?