jquery 如何显示未授权can can访问的错误

slwdgvem  于 2023-08-04  发布在  jQuery
关注(0)|答案(3)|浏览(89)

我正在使用Bootstrap,它有div class="alert notice",其中有一堆用于各种通知消息的类。
我也有一个 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

字符串
我在同一个控制器的私有方法中设置了@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警报中显示一个适当的错误,该错误在几秒钟内就会消失。
我该怎么做?

hgqdbh6s

hgqdbh6s1#

对于第一个,如果你使用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使这个helper不需要,因为它通过load_and_authorize_resource加载资源

更新2

您还需要确保您使用的是来自CanCanCommunity的最新版本的cancan和rails4,因为原来的旧版本不支持rails4
只要在你的Gemfile中使用这个

gem 'cancancan', '~> 1.9'


代替了

gem 'cancan'

dhxwm5r4

dhxwm5r42#

comments/destroy.js.erb文件中添加以下代码:

<% if defined?(@error) %>
  $('.alert.notice').text("<%= @error %>");
  $('.alert.notice').show();
  setTimeout(function() {
    $('.alert.notice').fadeOut('fast');
  }, 5000);
<% end %>

字符串
set_comment方法更改为使用find_by以避免获得RecordNotFound异常:

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


然后在你的控制器中你可以修改destroy动作如下:

def destroy
respond_to do |format|
  if @comment.present?
      @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.html { redirect_to root_url, notice: 'unauthorized access error.'  }
      format.js { @error = 'unauthorized access error' }  
  end
end


结束

bq3bfh9z

bq3bfh9z3#

我把它放在app/controllers/application_controller.rb中

## Handling unauthorized access: https://github.com/CanCanCommunity/cancancan#handle-unauthorized-access
  rescue_from CanCan::AccessDenied do |exception|
    respond_to do |format|
      format.json { head :forbidden, content_type: 'text/html' }
      format.html { redirect_to main_app.root_url, notice: exception.message }
      format.js   { head :forbidden, content_type: 'text/html' }
    end
  end

字符串

相关问题