5

In my routes.rb I have the following:

get "contact" => "inquiries#new"

So that when I go to /contact in the browswer, it calls the InquiriesController's new action.

Now when I try to call render "new" in the create action inside InquiriesController:

def create
    …
    render "new"
end

The resulting url in the browser is /inquiries.

Is there a way besides calling redirect_to to render "new" but have the url as /contact in the browser?

2
  • I'm agree that you should redirect_to if you want your address to be /contact but why do this ? i think there is no problem for your visitors to see the link change from contact to inquiries ! Commented Aug 6, 2013 at 11:40
  • @medBouzid you can see my answer on this with using unpoly Commented Jan 22, 2024 at 10:42

5 Answers 5

13

Short answer is No. And here's why:

render is different from redirect_to. When you write redirect_to :action, you are initiating an entirely new browser request. The rails stack is hit, again routes are searched for and the corresponding action is executed. Its exactly the same as entering the url in address bar and pressing enter.

On the other hand, when you use render, you are telling which view to use for the current request. As such, the address in the address bar will generally be of the action in which you are calling render. That's because you put an address and then you tell rails to display a different page in that same request.

In a nutshell, while redirect_to begins an entirely new request cycle, render simply replaces the default view with what you choose in the same request cycle.

So if you want the address bar to change, you will have to initiate a new request to the address you want. It can be by manually entering the address, clicking a link to that address or redirecting to it from rails.

Hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Is it not possible to call some javascript code to change that ? Turbolinks is is already doing similar stuff with browser history and AJAX requests. That No is most likely outdated.
5

The solution is to use custom routes, if you use Restful routing, you can simply add this line to your routes.rb :

resources :inquiries, path: "contact", as: :inquiries, only: [:create]

here you tell rails to change url by default from inquiries to contact when the name of the action is create

if you want other action to match an url which is begin with contact, just add the name of the action to "only", for example : only: [:create, :update ...]

if you want all your actions in that controller (inquiries) to be customized to "contact" just remove only like this :

resources :inquiries, path: "contact", as: :inquiries

and all your routes for inquiries controller will be change from /inquiries to /contact

for more details about how to customizing restful routes please check this link

Comments

3

When using render :new in the create action, it will use the same URL that the form posted to.

Therefore, if you would like to set up both an inquires you can set up your routes like:

get '/contact', 'inquiries#new', as: 'contact'
post '/contact', 'inquiries#create'

You can also use the resources method as medBo references, but I just prefer plain old get and post when I'm doing custom things. Also, these routes can co-exist with your exiting inquiries routes without any ill affects.

Then with those routes sets, you can create your contact from by writing:

<%= form_tag contacts_url do %>
   ...
<% end %>

The important step here, is that we set up the form to post to `/contact' instead of posting to '/inquiries'.

Comments

2

I think you first need to understand difference between redirect_to & render

For /contact url

change

render "new"

to

redirect_to "/contact"

Comments

0

A quite simple and faily straight forward way is to use Unpoly. This will allow you to replace the current DOM with the requested DOM at the matching a target.


Solution:

Unpoly also allows you to replace only specific targets with [up-target]-HTML-attribute along with some other strategies to do this too.

So when you call render in the controller this will not update the url. Unpoly treats all minor page fragments as no navigation event.


Example:

You can see this in action for Rails within the Unpoly demo when you click on "done" within any task. Within the bottom header you can see last targeted update with a link to the related code:

enter image description here


Also see:

You can read more on how Unpoly decides to update the history and how to customize that. You could even catch the history update event and tweak it as you want.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.