Description of my work environment: Rails 4.2.4, Ruby 2.3.1, SQL Server database, javascript on object html views
My controller that content an update action:
if @cs.update_attributes(cs_params_update)
flash[:notice] = "Centro de Saúde #{t(:record_successfully_updated)}"
# format.html { render :action => 'edit', :cs_id => @cs.id }
# Permance na mesma página após o update
format.html { redirect_to({:controller => :cs, :action=>:edit,
:method => :get,
:cs_id => @cs.id
})}
format.xml { head :ok }
else
format.html { render({:controller => :cs, :action=> :edit }) }
format.xml { render :xml => @cs.errors, :status => :unprocessable_entity }
end
When I try to edit as follows http://localhost:3000/cs/1/edit and to save something that is going to call a validation erron on my controller’s update action,
the validator display error validation as expected but instead rendering it redirects to show url as follows http://localhost:3000/cs/1 loosing the /edit suffix
I had previously seen this problem in some stackoverflow questions ->
How to make a render :edit call show the /edit in the address bar
Why the URL loses the '/edit' suffix after a failed validation?
In my case, I need to use :render, as my cancel button is sending me to the show due to the url and I can’t go to the show, I need to stay in the edit after clicking the cancel button.
In my view I use javascript that allows you to enable and disable elements, follow the code present in my application.js:
function EnablDisablElements(FieldsNames, Status){
if (FieldsNames) {
for (var h = 0; h < FieldsNames.length; h++) {
document.getElementById(FieldsNames[h]).disabled = Status;
}
}
}
2
Answers
It’s behaving correctly. I think you’re confusing the
show
url with theupdate
url. They are the same, but they have different HTTP verbs. It’sGET
forshow
andPATCH
for update.When your validation fails, you are in the #update method in your controller, but b/c the validation fails you render the
edit
view. That’s what this code doesformat.html { render({:controller => :cs, :action=> :edit }) }
. Actually you could just abbreviate that torender :edit
.Everything is working the way it should!
You’re falling victim to a common beginner hangup in Rails. Your app is actually behaving correctly but you’re expecting the wrong result.
Lets say you have a resource named
products
.In Rails the
GET /products/1/edit
action simply renders a form. It’s an idempotent action.When you then submit the form you send
PATCH /products/1
without the suffix. That’s because in REST you use the HTTP method to convey what’s happening. Not suffixes on the URL.When you then re-render the form with errors you’re displaying the result of performing a non-idempotent action. You’re responding to a form submission and that response is specific to just that request.
This is not the same thing as
GET /products/1/edit
and should not have the same URL.See: