简体   繁体   中英

Clarity on response formats and page reload for html response in Rails

I would like to understand the response format actions in Rails. Suppose I have a link_to in my partial which is rendered in show page like below:

show.html.erb

<%= render partial: 'my_partial', locals: { stage: @stage } %>

my_partial.html.erb

<% case 'stage' %>
<% when 'beginning' %>
  <%= link_to 'Submit', { controller: 'my_controller', action: 'update_model' } %>
<% when 'ongoing' %>
  <%= render partial: 'another_partial' %>
<% end %>

my_controller.rb

def update_model
  #do something
  respond_to do |format|
    format.json { render json: { some_key: some_value } }
    format.js { render partial: 'path_to_partial/partial.js' }
    format.html { redirect_to action: 'show' }
  end
end

Here whenever show page is loaded for the first time @stage will be beginning and then on clicking link_to 'Submit' then before the response from controller the @stage will be changed to ongoing .

Now Whenever I click on link_to , the page reloads and the response is in html so format.html is sent. If I add remote: true then the response is in js and the page does not reload because it is remote .

So the exact functionality that I want is to re render the show page and then inside the my_partial it should go to when ongoing and then render the another_partial page without reloading. This happens in the same url.

What I am trying to understand is why does the page reload when it is the same url? Is that how format.html works? What should I do to render the show page again but without reloading the page?

What the respond_to do |format| does it looks which response the incoming http request is expecting. Normally, if you click on a link or submit a form, it expects html. But, as you state correctly, if you add remote: true the http request issued by the link is expecting javascript. Now you want to rerender only the partial, not the whole page. You can do it like so in the controller

def update_model
 ...
  respond_to do |format|
    ...
    format.js 
    ...
  end
end

Don't give a block to format.js this will automatically render a file in the views which - like always - should be named like the controller action. So update_model.js.erb And here you can decide what to do. So for example find the div that holds your partial and then rerender it. Thanks to .erb you can write embedded ruby code in this js file too. And this is where you decide which part to rerender or whatever to do (toggle classes,...)

const container = document.querySelector("#container-for-partial")
const partial = "<%= j render 'some_partial' %>"
// Inject HTML to partial
container.innerHTML = partial

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM