2015-10-20 102 views
2

我的控制器之一的更新方法是這樣的:檢查保存更新後的Rails 4

def update 
    @node = Node.find(params[:id]) 
    @video = @node.media 
    @node.update(node_params) 
    @video.update(title: @node.name, description: @node.description) 
end 

我需要一個回調來確保該@node和@video更新。什麼是最好的方法來做到這一點?

+0

你需要一個特定的功能爲回調(例如做一些其他任務保存後),或者你只是檢查更新是否成功? – wspurgin

+0

我需要一個特定的功能。我的前端UI開發人員有一些我需要回調的jQuery。有點新的AJAX的東西,讓我知道你是否需要更多的信息。我想我可以用UJS創建條件(update.js.erb)。我可以弄清楚,但我的主要問題是我不知道如何檢查保存然後執行一個功能。我無法弄清楚'after_save'是否會起作用,如果可以,我將如何實現它。 – mike0416

+0

我想我需要更多的信息。您想要返回一個帶回調的URL,以驗證視頻/節點是否已更新?這樣你的UI開發人員可以發送一個AJAX請求給它? 或者你是否在說,根據視頻和節點是否更新正確,你想發送回調? – wspurgin

回答

1

如果更新成功,您可以測試...

if @node.update(node_params) 
    # handle success 
    if @video.update(title: @node.name, description: @node.description) 
     # etc... 
    end 
    else 
    # handle fail 
    end 

在一個Ajax請求,你可以把狀態視圖:

<% if @node.errors.any? %> 
    alert('<%= j(@node.errors.full_messages.join("\n")) %>'); 
<% else %> 
    alert('Success') 
<% end %> 
+0

這被標記爲答案的第一部分的正確的B/C。 – mike0416

0

根據你說的話,我覺得這是你可能會想要什麼

def update 
    @node = Node.find(params[:id]) 
    @video = @node.media 
    @node_saved = true 
    @video_saved = true 
    begin 
     @node.update_attirbutes!(node_params) 
    rescue ActiveRecord::RecordInvalid 
     @node_saved = false 
    end 

    begin 
     @video.update_attributes!(title: @node.name, description: @node.description) 
    rescue ActiveRecord::RecordInvalid 
     @video_saved = false 
    end 

    render "mypage" 
end 

裏面你update.js.erb

... 
if (<%= @node_saved %> === false) { 
    // trigger flash message 
}; 

if (<%= @video_saved %> === false) { 
    // trigger flash message 
}; 

我仍可能誤會你想要什麼,但是這或@Swards answer應該回答你的問題。

+0

謝謝@TheSpurg。讓我更進一步。如果我想在'update.js.erb'而不是'my_callback'中做什麼?例如,如果兩個更新都正確地拋出一條更新成功的閃存消息,但是如果它沒有拋出更新不成功的提示? – mike0416

+0

也許設置一些變量,你會傳遞給你的模板?這將是一種方法。 – wspurgin

+0

@ mike0416根據您的評論進行了更新。這更多的是你在尋找什麼? – wspurgin

0

Rails的.save和。 update返回true/false(布爾值)取決於操作是否成功。

利用,在你的流程如下的標準方式:

def update 
    @node = Node.find params[:id] 

    respond_to do |format| 
    if @node.update(node_params) 
     format.js #-> invokes /views/nodes/update.js.erb 
     format.json { render json: @node.to_json } 
     format.html 
    else 
     format.js #-> invokes /views/nodes/update.js.erb 
     format.json 
     format.html 
    end 
    end 
end 

不應使用完全相同的數據爲@node使用@video.update - 你可以做的是,在模型。你最好使用關聯等,如果需要我可以解釋。

#app/models/node.rb 
class Node < ActiveRecord::Base 
    belongs_to :media #? 
    before_save :set_media, on: :update 

    private 

    def set_media 
    self.media.name = self.name 
    self.media.description = self.description 
    end 
end 

阿賈克斯

我的前端UI開發人員有一定的jQuery,我需要爲

回調因爲我不知道這樣做的規範,我無法給你任何特定的代碼。

可以告訴你的是,如果你正在使用AJAX,你必須確保你理解服務器端 & 客戶端代碼之間的差異。

我不想侮辱你的智商,但我會解釋它爲後人的緣故......

前端AJAX看起來就像這樣:

#app/assets/javascripts/application.js 
$(document).on("click", ".element", function(){ 
    $.ajax({ 
     url: "...", 
     data: ...., 
     success: function(data) { }, 
     error: function(response) {} 
    }); 
}); 

...因爲這是客戶端代碼,您只能處理來自服務器的數據返回。一個常見的誤解是許多人認爲他們會以某種方式在此使用Ruby代碼/方法。沒有。

您可以預封裝的數據只能發送回本,所以如果你想你的數據是條件,你會做這樣的事情:

def update 
    @node = Node.find params[:id] 
    @returned = "yes" if @node.update(node_params) 
    render [x], layout: !request.xhr? 
end 

這將允許你發回數據的條件,與您就可以使用前端JS來操作:

$.ajax({ 
... 
success: function(data) { 
    ... do something with data 
} 

-

如果你想使用服務器端代碼,您會得到更好的使用內置的format.js功能:

def update 
    @node = Node.find params[:id] 
    respond_to do |format| 
     format.js #-> app/views/nodes/update.js.erb 
    end 
end 

確實允許您使用Ruby代碼,因爲JS是服務器端呈現,並傳遞給瀏覽器。我不知道至於細節,但我知道你可以用它做如下:

#app/views/nodes/update.js.erb 
<% if @node.something %> 
    $("js").... 
<% else %> 
    ... 
<% end %>