program tip

Rails 3에서 리소스 생성 작업이 실패하고 render : new를 호출 할 때 URL이 리소스의 인덱스 URL로 변경되어야하는 이유는 무엇입니까?

radiobox 2020. 12. 26. 09:50
반응형

Rails 3에서 리소스 생성 작업이 실패하고 render : new를 호출 할 때 URL이 리소스의 인덱스 URL로 변경되어야하는 이유는 무엇입니까?


도서라는 리소스가 있습니다. 내 경로 파일에 리소스로 올바르게 나열됩니다.

새로운 뷰에 표준을 제공하는 새로운 작업이 있습니다.

@book = Book.new

모델에는 존재에 의해 유효성이 검증되는 몇 가지 속성이 있으므로 저장 조치가 실패하면 오류가 생성됩니다.

내 컨트롤러에서 :

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

이것은 꽤 표준입니다. render : new를 사용하는 이유는 객체가 뷰로 다시 전달되고 오류를보고하고 양식 항목을 다시 채울 수 있다는 것입니다.

이것은 (render : new를 통해) 양식으로 다시 보낼 때마다 오류가 표시되는 것을 제외하고는 작동하지만 내 URL은 INDEX URL입니다.

/books

보다는

/books/new

제가 처음 시작한 곳입니다. 이 문제에 대한 여러 게시물을 보았지만 답변이 없습니다. 최소한 / books / create에 도착할 것이라고 가정합니다.이 파일에는보기 파일도 있습니다 (이 경우 new와 동일).

나는 이것을 할 수있다 :

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

그러나 @book 데이터는 오류 메시지와 함께 손실되며 이는 양식 및 작업 등을 갖는 전체 요점입니다.

일반적으로 해당 URL이 모든 도서를 나열하는 INDEX 메소드를 호출 할 때 render : new가 내 색인 작업 인 / books에 나를 방문하는 이유는 무엇입니까?


실제로 되어 생성 경로에 당신을 보낼. HTTP 메소드 POST를 사용하여 create경로 가 인 작업에 /books있습니다. 이것은 색인 경로와 동일하게 보이지만 /books색인 경로는 HTTP 메소드 GET을 사용하고 있습니다. 레일 라우팅 코드는 호출 할 작업을 결정할 때 메서드를 고려합니다. 유효성 검사가 실패한 후에도 여전히 만들기 작업에 있지만 new뷰를 렌더링하고 있습니다. 약간 혼란 스럽지만 같은 줄 render :new은 실제로 새 작업을 전혀 호출하지 않습니다. 여전히 create 액션을 실행하고 있으며 Rails에게 새로운 를 렌더링하도록 지시 합니다 .


저는 Rails-Tutorial로 시작했고 같은 문제가있었습니다. 해결책은 간단합니다. 양식을 제출 한 후 (오류 포함) 동일한 URL을 원하면 새 항목을 결합하고 하나의 작업으로 작업을 만듭니다.

이것이 가능하게 만드는 코드의 일부입니다 (누군가에게 도움이되기를 바랍니다 ^^)

route.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 %>

똑같은 질문이 있었기 때문에 언젠가 누군가에게 도움이 될 것입니다. 내 솔루션이 여전히 이상적이지는 않지만 기본적으로이 작업을 수행하려면 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) 플래시 해시를 파싱 할 때마다 플래시 [: book]를 필터링해야합니다.

--> correct URL is displayed, Form data is preserved. Still, I somehow don't like putting the user object into the flash hash, I don't think that's it's purpose. Does anyboy know a better place to put it in?


It doesn't land you at /books/new since you are creating resource by posting to /books/. When your create fails it is just rendering the new action, not redirecting you to the new action. As @MrYoshiji says above you can try redirecting it to the new action, but this is really inefficient as you would be creating another HTTP request and round trip to the server, only to change the url. At that point if it matters you could probably use javascript change it.


It can be fixed by using same url but different methods for new and create action.

In the routes file following code can be used.

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

Now you new page will render at url

books/common_path_string

In case any errors comes after validation, still the url will be same.

Also in the form instead using

books_path

use

url: common_path_string_books_path, method: :post

Choose common_path_string of your liking.

ReferenceURL : https://stackoverflow.com/questions/14490098/in-rails-3-when-a-resource-create-action-fails-and-calls-render-new-why-must

반응형