jquery - 如何显示未经授权的可以访问的错误

标签 jquery ruby-on-rails ruby-on-rails-4 twitter-bootstrap-3 cancan

我正在使用 Bootstrap,它有 div class="alert notification",它有一堆用于各种通知消息的类。

我还有一个针对评论的 AJAX 销毁操作,我已添加了 cancan 授权。当我尝试删除 current_user 无权访问的评论时,它不起作用 - 这是正确的。

但我想要发生的是在 Bootstrap 样式的 div 中弹出错误消息 5 - 10 秒,然后消失。

这是我的 CommentsController.rb 上的 destroy 操作

  def destroy
    respond_to do |format|
      if @comment.destroy
          format.html { redirect_to root_url, notice: 'Comment was successfully deleted.'  }
          format.json { head :no_content }
          format.js   { render :layout => false }      
      else
          format.json { render json: @comment.errors, status: :unprocessable_entity }  
      end
    end        
  end

我在同一 Controller 的私有(private)方法中设置了@comment:

  private
    def set_comment
      @comment = current_user.comments.find(params[:id])
    end

这是我的comments/destroy.js.erb

$('.delete_comment').bind('ajax:success', function() {  
        $(this).closest('div#new_comment').fadeOut();
});  

但这并不影响未经授权的访问。

在我的ability.rb中,我有这个:

can :manage, Comment, user_id: user.id

在我的日志中,当我尝试删除我无权访问的评论时,我会在日志中看到以下内容:

Started DELETE "/comments/5" for 127.0.0.1 at 2014-10-16 02:56:53 -0500
Processing by CommentsController#destroy as JS
  Parameters: {"id"=>"5"}
  User Load (0.4ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
  FamilyTree Load (0.2ms)  SELECT  "family_trees".* FROM "family_trees"  WHERE "family_trees"."user_id" = $1 LIMIT 1  [["user_id", 1]]
  ReadMark Load (0.1ms)  SELECT  "read_marks".* FROM "read_marks"  WHERE "read_marks"."user_id" = $1 AND "read_marks"."readable_type" = 'PublicActivity::ORM::ActiveRecord::Activity' AND "read_marks"."readable_id" IS NULL  ORDER BY "read_marks"."id" ASC LIMIT 1  [["user_id", 1]]
  Comment Load (0.3ms)  SELECT  "comments".* FROM "comments"  WHERE "comments"."user_id" = $1 AND "comments"."id" = $2 LIMIT 1  [["user_id", 1], ["id", 5]]
Completed 404 Not Found in 8ms

ActiveRecord::RecordNotFound - Couldn't find Comment with 'id'=5 [WHERE "comments"."user_id" = $1]:

这是完美的。

我想做的就是在 Bootstrap 警报中显示适当的错误,该错误会在几秒钟内消失。

我该如何实现这一目标?

最佳答案

首先,如果您使用 cancan - 只需使用 cancan:

#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
  load_and_authorize_resource #this will set @comment by your ability and authorize action
  ...
end

这将引发 CanCan::AccessDenied 而不是 ActiveRecord::RecordNotFound 错误。

让我们用rescue_from在ApplicationController中捕获它

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  ...
  rescue_from CanCan::AccessDenied do |exception|
    @error_message = exception.message
    respond_to do |f|
      f.js{render 'errors/error', status: 401}
    end
  end
end

对于弹出通知,我使用 PNotify 库 http://sciactive.github.io/pnotify/ 它将在右上角显示错误,然后隐藏。 只需将其包含在您的项目中,您就可以显示如下错误:

#app/views/errors/error.js.erb
new PNotify({
  title: 'Oh No!',
  text: '<%=@error_message%>',
  type: 'error'
});

此代码可让您避免因不良做法而捕获 ActiveRecord::RecordNotFound 错误。

更新

我忘记了一些事情!您必须删除 set_comment 方法和 before_action 或像这样编写:

before_action :set_comment
...
private
def set_comment
  @comment ||= current_user.comments.find(params[:id])
end

此回调覆盖了代码中 load_and_authorize_resource 的 @comment 变量。 Cancan 不需要这个助手,因为它通过 load_and_authorize_resource

加载资源

更新2

您还需要确保您使用的是最新版本的 cancan 和 CanCanCommunity 中的 rails4因为原来的旧版本不支持rails4

只需在 Gemfile 中使用它

gem 'cancancan', '~> 1.9'

而不是

gem 'cancan'

关于jquery - 如何显示未经授权的可以访问的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26399269/

相关文章:

jquery - 路口观察者 API 不可用

ruby-on-rails - 在 Rails 中链接两个 Controller

ruby-on-rails - 使用 Carrierwave 将不同版本的图像存储到不同的位置

jquery 单击 href 链接 - 必须单击两次

javascript - 触发点击事件到项目列表

ajax - jQuery 单击事件的行为与 Firefox 中的实时功能不同

ruby-on-rails - 使用 Ruby Gem 将联系人添加到 InfusionSoft DB 失败

ruby-on-rails - ruby rails : How to delete unused tags with acts-as-taggable-on?

javascript - Rails 中的共享 JS(咖啡)

ruby - 如何在 Rails 4 中使用表单对象之前的验证回调?