2016-01-22 60 views
2

在Rails應用中使用常規路由vs AJAX時,我遇到了不一致的行爲。我有一個鏈接,其功能是摧毀一個has_many :through關係。當AJAX不使用時,沒有問題。當使用AJAX(即remote:true)時,鏈接會破壞關係以及所有者對象。Rails:使用has_many關係時link_to(...,remote:true)的行爲不一致

下面是詳細信息:

我有一個模型ReaderBook,並Favorite一個簡單的應用程序。閱讀器has_many通過收藏夾預訂,並通過收藏夾閱讀has_many閱讀器。當我使用「從收藏夾中刪除」鏈接時,當使用AJAX時,本書也會被銷燬。如果我沒有remote:true,則不會發生此問題。這裏是服務器日誌:

Started DELETE "/favorites/5" for ::1 at 2016-01-22 08:06:03 -0800 
Processing by FavoritesController#destroy as JS 
    Parameters: {"id"=>"5"} 
    Favorite Load (0.2ms) SELECT "favorites".* FROM "favorites" WHERE  "favorites"."id" = ? LIMIT 1 [["id", 5]] 
    Book Load (0.1ms) SELECT "books".* FROM "books" WHERE "books"."id"  = ? LIMIT 1 [["id", 5]] 
    (0.1ms) begin transaction 
    SQL (0.3ms) DELETE FROM "favorites" WHERE "favorites"."id" = ?  [["id", 5]] 
    (1.9ms) commit transaction 
Redirected to http://localhost:3000/books/5 
Completed 302 Found in 5ms (ActiveRecord: 2.5ms) 


Started DELETE "/books/5" for ::1 at 2016-01-22 08:06:03 -0800 
Processing by BooksController#destroy as JS 
    Parameters: {"id"=>"5"} 
    Book Load (0.1ms) SELECT "books".* FROM "books" WHERE "books"."id"  = ? LIMIT 1 [["id", 5]] 
    (0.1ms) begin transaction 
    Favorite Load (0.2ms) SELECT "favorites".* FROM "favorites" WHERE  "favorites"."book_id" = ? [["book_id", 5]] 
    SQL (0.2ms) DELETE FROM "books" WHERE "books"."id" = ? [["id", 5]] 
    (0.9ms) commit transaction 
Redirected to http://localhost:3000/books 
Completed 302 Found in 7ms (ActiveRecord: 1.5ms) 

這裏是我認爲是相關代碼:

book.rb

class Book < ActiveRecord::Base 
    has_many :favorites, class_name: "Favorite", 
        foreign_key: "book_id", 
        dependent: :destroy 
    has_many :readers, through: :favorites 
end 

reader.rb

class Reader < ActiveRecord::Base 
    has_many :favorites, class_name: "Favorite", 
        foreign_key: "reader_id", 
        dependent: :destroy 
    has_many :books, through: :favorites 
    def add_favorite(book) 
    return if Favorite.exists?(book_id:book.id,reader_id:self.id) 
    favorites.create(book_id: book.id, reader_id: self.id) 
    self.reload 
    end 
end 

喜愛。 rb

class Favorite < ActiveRecord::Base 
end 

如果沒有讀書關係,並且在書籍閱讀器關係中存在「從收藏夾中刪除」,則書籍/表演視圖中的「link_to」表示「添加到收藏夾」。正確的鏈接在輔助模塊中生成。

books_helper.rb

module BooksHelper 
    def favorites_link_for(reader, book) 
    if reader && Favorite.exists?(book_id: book.id, reader_id: reader.id) 
     link_to("Remove From Favorites", Favorite.find_by(book_id: book.id, reader_id: reader.id), :method => 'delete', remote: true) 

    elsif reader && !Favorite.exists?(book_id: book.id, reader_id: reader.id) 
     link_to("Add To Favorites", favorites_path(book_id: book.id, reader_id: reader.id), :method => 'post', remote: true) 
    end 
    end 
end 

唯一關注的控制器favorites_controller.rb:

class FavoritesController < ApplicationController 
    def create 
    reader = Reader.find(params[:reader_id]) 
    @book = Book.find(params[:book_id]) 
    reader.add_favorite(Book.find(params[:book_id])) 
    redirect_to @book 
    end 

    def destroy 
    debugger 
    fav = Favorite.find(params[:id]) 
    @book = Book.find(fav.book_id) 
    fav.destroy 
    redirect_to @book 
    end 
end 

而且唯一感興趣的觀點是書籍/顯示:

<p id="notice"><%= notice %></p> 

<p> 
    <strong>Name:</strong> 
    <%= @book.name %> 
    <%= favorites_link_for(Reader.last, @book) %> 
</p> 

<%= link_to 'Edit', edit_book_path(@book) %> | 
<%= link_to 'Back', books_path %> 

的完整代碼可在此處獲得:https://github.com/JenDobson/rails-with-remote-issue/tree/broken Rails版本是4.2.2。

回答

0

問題是由FavoritesController#destroy中的redirect_to @book行引起的。當我刪除那條線時,一切正常。該行需要修改,以允許html和js下的不同頁面響應,但我仍然不明白爲什麼redirect_to @book會導致書籍記錄在JS下被刪除,而不是在HTML下。我很高興接受任何能夠進一步啓發我的人的回答。

的固定控制器看起來是這樣的:

class FavoritesController < ApplicationController 
def create 
    @reader = Reader.find(params[:reader_id]) 
    @book = Book.find(params[:book_id]) 
    @reader.add_favorite(Book.find(params[:book_id])) 
    respond_to do |format| 
     format.html { redirect_to @book } 
     format.js 
    end 
end 

def destroy 
    fav = Favorite.find(params[:id]) 
    @book = Book.find(fav.book_id) 
    @reader = Reader.find(fav.reader_id) 
    fav.destroy 
    respond_to do |format| 
     format.html { redirect_to @book } 
     format.js 
    end 
    end 
end 

在GitHub上的代碼已定:https://github.com/JenDobson/rails-with-remote-issue/tree/master