Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

ruby on rails - How to make a render :edit call show the /edit in the address bar

In the update action of my preferences controller in my Rails app, if there are any errors in the validation/save etc there's a call to:

format.html { render :edit }

Nothing too unusual there - however, when this code is hit, the address in the browser changes and loses the /edit in the URL.

For example:

To start with, my browser shows I am on the page at following address: http://localhost:3000/preferences/1/edit

However, once the errors are detected and the render is called the address in the is changed to http://localhost:3000/preferences/1

I can't say I've ever noticed this behaviour before - but Is there a way to force the /edit to stay on the end of the URL? Without the /edit it is effectively showing the URL of the show page (and I don't have a template for that!)

Many thanks, Ash

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Instead of calling render, you can redirect_to the edit page, and use flash to keep track of the model:

def update
  # ...
  if !@model.save # there was an error!
    flash[:model] = @model
    redirect_to :action => :edit
  end
end

And then in the edit action you can reload the values from flash[:model], ie:

def edit
  if flash[:model]
    @model = flash[:model]
  else
    @model = ... # load model normally
  end
end

Update:

As commented below, I think when I wrote this answer I was trying to provide a way to both update the URL (which requires a redirection) and keep the changed attributes of the model, which is why the model was stored in flash. However, it's a pretty bad idea to stick a model into flash (and in later versions of Rails it'll just get deserialized anyways), and RESTful routes don't really require making the URL contain edit.

The usual pattern would be to just render the edit action with the model already in memory, and forego having the "ideal" URL:

def update
  # Assign attributes to the model from form params
  if @model.save
    redirect_to action: :index
  else
    render :edit
  end
end

Alternately, if it's preferable to have the "ideal" URL and you don't care about maintaining changed attributes that failed validation, see @jamesmarkcook's answer.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...