2011-12-02 62 views
4

我已經實現了一個基於ajax的按鈕來添加和刪除用戶的「願望清單」中的日曆事件。該按鈕表現爲一個切換開關。如果該活動已經在他們的願望清單上,它將刪除它;如果不是,那麼它會添加它。如何正確設置ajax button_to上的路線?

我的問題是,該按鈕可以在第一次加載頁面時正常工作,但是在點擊它並用新的button_to替換爲AJAX後,它不再有效。

我看着this post但他有一個稍微不同的架構,我不想完全重構這個,只是如果我能避免它。我有一個保存事件的單獨模型。這裏有三種模式:用戶,事件和saved_events。用戶和事件之間存在多對多的關係,這表示爲saved_event。這裏是模型的相關代碼。

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 

我已經配置相當標準的路線。

的routes.rb:

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

我最初想看看這個按鈕的事件的頁面,所以我把它添加到該事件的show.html.erb。 (我知道這是不是很乾,但 - 我在等待,直到它正常工作,將其移動到部分)

事件/ show.html.erb:

<% if [email protected]_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 

我與阿賈克斯的目標是剛剛換出加形式與刪除表單(反之亦然)。所以我有一個create.js.erb和一個destroy.js.erb,它們使用來自events/show.html.erb的相同代碼。

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) %>"); 

這是我在日誌中看到,如果第二個按鈕點擊是「刪除」

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"): 

這是我在日誌中看到,如果第二個按鈕是點擊‘加’

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"): 

在初始加載頁面時,添加按鈕有「/ saved_events?ID = 1「作爲它的動作,所以我很困惑,爲什麼它會是」/ saved_events/1「的第二個按鈕點擊。

回答

1

這似乎是問題來自我的jquery。一個div,然後在那個div上調用jquery.html()而不是形式本身。我在控制器中做了一些其他的重構,爲了簡潔起見我不會在這裏發佈,但這裏是我的新js.erb文件:

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) %>");