2012-03-21 22 views
7

Tôi muốn bộ nhớ cache một cái nhìn Post, nhưng quan điểm phụ thuộc vào các điều khoản của người sử dụng hiện tại (ví dụ, tôi chỉ hiển thị "chỉnh sửa" liên kết nếu current_user.can?(:edit, @post))Nhận một chuỗi đại diện cho khả năng Cancan của người dùng

Vì vậy, Tôi muốn khóa bộ nhớ cache của tôi bao gồm một đại diện cho khả năng của người dùng hiện tại CanCan, để tôi có thể làm mất hiệu lực bộ nhớ cache khi khả năng của người dùng thay đổi

SO: làm thế nào tôi có thể nhận được chuỗi đại diện cho khả năng của người dùng hiện tại 2 người dùng khác nhau có cùng khả năng sẽ tạo ra "chuỗi khả năng" giống nhau?

Tôi đã thử user.ability.inspect, nhưng điều này không tạo ra chuỗi tương tự cho người dùng khác nhau có khả năng tương tự

+0

bỏ lỡ tiền thưởng đó! :( – RGB

Trả lời

7

EDIT: sửa đổi cho CanCanCan

Tính đến phiên bản 1.12 của CanCanCan (các tiếp tục cộng đồng của CanCan), Ability.new(user).permissions trả về một băm với tất cả các quyền cho người dùng đã cho.

câu trả lời

trước (Cancan):

Đây có thể là một chút phức tạp ... nhưng ở đây nó đi ..

Nếu bạn vượt qua người dùng chỉ định vào mô hình Khả năng theo yêu cầu của Cancan, bạn có thể truy cập vào định nghĩa của người dùng vai trò sử dụng instance_variable_get, và sau đó phá vỡ nó xuống bất cứ điều gì giá trị chuỗi bạn muốn từ đó ..

>> u=User.new(:role=>"admin") 
>> a=Ability.new(u) 
>> a.instance_variable_get("@rules").collect{ 
     |rule| rule.instance_variable_get("@actions").to_s 
    } 
=> ["read", "manage", "update"] 

nếu bạn muốn biết các mô hình trong đó những quy tắc trong flicted khi, bạn có thể truy cập vào biến @subjects dụ để có được tên của nó ..

đây là cách bố trí mô hình cho khả năng mà từ đó tôi làm việc với (pp)

Ability:0x5b41dba @rules=[ 
    #<CanCan::Rule:0xc114739 
    @actions=[:read], 
    @base_behavior=true, 
    @conditions={}, 
    @match_all=false, 
    @block=nil, 
    @subjects=[ 
     User(role: string)]>, 
    #<CanCan::Rule:0x7ec40b92 
    @actions=[:manage], 
    @base_behavior=true, 
    @conditions={}, 
    @match_all=false, 
    @block=nil, 
    @subjects=[ 
     Encounter(id: integer)]>, 
    #<CanCan::Rule:0x55bf110c 
    @actions=[:update], 
    @base_behavior=true, 
    @conditions={:id=>4}, 
    @match_all=false, 
    @block=nil, 
    @subjects=[ 
     User(role: string)]> 
] 
+0

Tôi đoán tổng hợp nó, bạn sẽ phải xây dựng các mảng với nội dung của sự lựa chọn của bạn, lưu nó, và sau đó chuyển đổi nội dung của nó thành chuỗi bằng cách sử dụng to_s một lần nữa! :) – RGB

+0

Đây là một hack dựa vào chi tiết triển khai. – tmandry

+0

Điều duy nhất điều này dựa vào là người dùng đang sử dụng đá quý CanCan, đó là những gì OP đang sử dụng. Các lớp Khả năng và Người dùng vốn đã có sẵn khi sử dụng CanCan – RGB

5

tôi muốn gửi những khả năng của tôi để JS, và để theo dõi trên bài đăng này, đây là phương pháp trợ giúp của tôi mà bạn có thể sử dụng để chuyển đổi khả năng của người dùng thành một mảng trong bộ điều khiển của bạn. Tôi sau đó gọi .to_json trên mảng một vượt qua nó để javascript.

def ability_to_array(a) 
    a.instance_variable_get("@rules").collect{ |rule| 
    { 
    :subject => rule.instance_variable_get("@subjects").map { |s| s.name }, 
    :actions => rule.instance_variable_get("@actions").map { |a| a.to_s } 
    } 
} 
end 

Và đây là mô hình Backbone.js của tôi mà thực hiện các lon) phương pháp (:

var Abilities = Backbone.Model.extend({ 
    can : function(action, subject) 
    { 
    return _.some(this.get("abilities"), function(a) { 
     if(_.contains(a["actions"], "manage") && _.contains(a["subject"], "all")) return true; 
     return _.contains(a["actions"], action) && _.contains(a["subject"], subject); 
    }); 
    } 
}); 
+0

Bạn cũng có thể sử dụng: subject => rule.instance_variable_get ("@ subject"). Map {| s | s.to_s}, như thể bạn sử dụng s.name và chủ đề của bạn chứa các ký hiệu sẽ bị lỗi – SteveA