Overriding the JavaScript template used in the Rails remote form view

I have a Rails application that doesn't seem to run the expected .js.erb file, so I would like to override the default behavior, but I'm not sure how to do this.

Details:

This is a Rails 3 application that displays a button_to with an AJAX call to switch the state of something to the backend, and then changes the button text to reflect the opposite action if you click it again. Basically, โ€œSave to Scheduleโ€ becomes โ€œRemove from Schedule,โ€ and you can click it again to do the opposite.

This really works fine, but only if I put the jQuery that I want to execute in show.js.erb (named after the view associated with the method that shows the page the button is on), and not toggle.js.erb ( depending on the name of the actual method being called).

In this example, I am using jquery-rails.

In the view that displays the button ( show.html.erb (more precisely, a partial call from there):

 <% if current_user.shows.include?(@show) %> <p><%= button_to "Remove from schedule", toggle_show_path(@show), :remote => true, :class => 'schedule_button' %> <% else %> <p><%= button_to "Save to schedule", toggle_show_path(@show), :remote=> true, :class => 'schedule_button' %> <% end %> 

From routes.rb :

 match '/shows/toggle/:id' => 'shows#toggle', :as => :toggle_show 

From my `show_controller.rb:

 def toggle if current_user show = Show.find(params[:id]) if show if current_user.shows.include?(show) current_user.shows.delete(show) flash[:notice] = "This show has been removed from your schedule." else current_user.shows << show flash[:notice] = "This show has been added to your schedule." end else flash[:error] = "Unknown show." end else flash[:error] = "You're not logged in." end end 

I assume that there are some default conventions that determine which .js.erb file to use, but why doesn't it use the one that is based on the method provided by the form?

I experimented with an explicit message of what to do, but I'm not quite sure how to specify the name of my alternate .js.erb file to call. It doesn't seem to be that way:

 respond_to do |format| format.html { redirect_to show_path(params[:id]) } format.js { render toggle_show_path(params[:id]) } end 

From my journal:

 ActionView::MissingTemplate (Missing template /shows/toggle/22 with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:js, :html], :locale=>[:en, :en]} in view paths "/Data/Sites/tvgridthing.local/app/views", "/Users/jschuur/.rvm/gems/ruby-1.9.2-p0/gems/devise-1.1.3/app/views", "/Data/Sites/tvgridthing.local", "/"): app/controllers/shows_controller.rb:78:in `block (2 levels) in toggle' app/controllers/shows_controller.rb:76:in `toggle' 

I assume that since I want to override the default behavior, I can no longer use Rails 3 shorter 'response_with format?

Unrelated question: Any way to condensate my show add / remove logic into my user model? I do a search, turn on and add / remove and wonder if there is a simpler solution.

Update: I just figured this out with the help of someone I sent this link to. The solution was simple: render :toggle .

It is still interesting if there are suggestions for optimizing the switching logic.

+2
source share
1 answer

If you change

 format.js { render toggle_show_path(params[:id]) } 

To just

 format.js 

By default, it will go to a file called toggle.js.erb in the views / shows of the folder, since you are inside a method that switches to the controller.

If you are inside the show method, then yes, your only solution

 render :toggle 

or

 render :action => 'toggle' 

Hope this helps

0
source

Source: https://habr.com/ru/post/1384383/


All Articles