Reputation: 1139
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?
Upvotes: 0
Views: 71
Reputation: 2715
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
Upvotes: 1