How to configure routes on the ajax_to button?

I have implemented an ajax-based button to add and remove a calendar event from a custom "wish list". The button behaves like a toggle switch. If an event is already included in their wish list, it will delete it; if it is not, then it will add it.

My problem is that the button works correctly when the page first loads, but after clicking it and replacing it with the new button on AJAX, it no longer works.

I looked at this post , but it has a slightly different architecture, and I donโ€™t want to completely refactor it, but if I can avoid it. I have a separate model for saved events. There are three models here: users, events, and save_events. There are many, many relationships between users and events that are represented as saved_event. Here is the corresponding code from the models.

user.rb:

has_many :saved_events has_many :events, :through => :saved_events 

event.rb:

  has_many :saved_events has_many :watchers, :class_name => "User", :through => :saved_events, :source => :user 

saved_event.rb:

  belongs_to :event belongs_to :user 

I set up pretty standard routes.

routes.rb:

  resources :saved_events, :only => [:index,:create,:destroy] resources :users resources :events 

First I want to see this button on the events page, so I added it to event show.html.erb. (I understand that this is not completely DRY yet - I wait while it works correctly to move it to partial)

Events / show.html.erb:

  <% if !@is _watched %> <%= button_to "Add to Wishlist", { :action => 'create', :controller => 'saved_events', :id => @event.id }, :remote => true %> <% else %> <%= button_to "Remove from Wishlist", saved_event_path(@event), :remote => true, :method => 'delete' %> <% end %> 

events_controller.rb:

  def show @event = Event.find(params[:id]) @is_watched = @event.watchers.exists?(current_user) if !current_user.nil? respond_to do |format| format.html # show.html.erb format.xml { render :xml => @event } format.json { render :json => @event } end end 

saved_events_controller.rb:

  def create logger.debug params.to_yaml @event = Event.find(params[:id]) if !current_user.events.exists?(params[:id]) current_user.events << @event end respond_to do |format| format.js end end def destroy logger.debug params.to_yaml @event = current_user.events.find(params[:id]) current_user.events.delete(@event) respond_to do |format| format.js end end 

My goal with ajax was to change the add form to the delete form (or vice versa). So I have create.js.erb and destroy.js.erb that just use the same code from /show.html.erb events.

saved_events / create.js.erb:

 $(".button_to").html("<%= escape_javascript button_to "Remove from Wishlist", saved_event_path(@event), :remote => true, :method => 'delete' %>"); 

saved_events / destroy.js.erb:

 $(".button_to").html("<%= escape_javascript (button_to "Add to Wishlist", { :action => 'create', :controller => 'saved_events', :id => @event.id }, :remote => true) %>"); 

This is what I see in the log if the second click of the button is โ€œdeleteโ€

 Started DELETE "/saved_events?id=1" for 127.0.0.1 at 2011-12-02 11:56:58 -0600 ActionController::RoutingError (No route matches [DELETE] "/saved_events"): 

This is what I see in the log if the second click of the button is โ€œaddโ€

 Started POST "/saved_events/1" for 127.0.0.1 at 2011-12-02 11:59:12 -0600 ActionController::RoutingError (No route matches [POST] "/saved_events/1"): 

When the page loads, the add button has "/ saved_events? Id = 1" as its action, so I'm confused as to why it would be / saved_events / 1 for the second button click.

+4
source share
1 answer

It seems the problem was in my jquery. I needed to wrap the form in a div, and then call jquery.html () on that div, and not in the form itself. I did some other refactoring in controllers that I will not post here for brevity, but here are my new js.erb files:

create.js.erb:

 <% button_html = button_to( 'Remove from Wishlist', { :action => 'destroy', :id => @saved_event.id }, :remote => true, :method => 'delete' ) %> $("#toggle_wishlist").html("<%= escape_javascript( button_html ) %>"); 

destroy.js.erb:

 $("#toggle_wishlist").html("<%= escape_javascript( button_to("Add to Wishlist", { :action => 'create', :controller => 'saved_events' }, :remote => true)) %>"); $("#toggle_wishlist .button_to").append("<%= escape_javascript( hidden_field_tag :event_id, @event.id ) %>"); 
+1
source

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


All Articles