2015-10-20 57 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 %>