【问题标题】:Testing value of a hash key with CanCan使用 CanCan 测试哈希键的值
【发布时间】:2013-04-23 13:51:44
【问题描述】:

我有一个带有序列化哈希的 UserProfile 模型,它定义了各种隐私选项:

class UserProfile < ActiveRecord::Base
  attr_accessible :bio, :first_name, :last_name, :location, :website_url, :vanity_url, :avatar
  belongs_to :user
  has_one :avatar
  before_create :default_privacy

  PRIVACY_SETTINGS = [:public, :app_global, :contacts, :private]
  serialize :privacy_options, Hash

  private

  def default_privacy
    return if self.privacy_options
    self.privacy_options = {:personal => :app_global, :contacts => :app_global, :productions => :app_global}
  end

end

我正在使用 CanCan 授权访问用户配置文件,如下所示:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    can :create, UserProfile
    can :read, UserProfile, :privacy_options[:personal].eql?(:public)
    if user.role? :user
      can :read, UserProfile, privacy_options[:personal].eql?(:cp_global)
      can :update, UserProfile, :user_id => user.id
    end
  end

end

但是,以下单元测试会产生 test_user_can_only_read_profile_with_personal_scope_set_to_public(AbilityTest): TypeError: can't convert Symbol into Integer

require 'test_helper'

class AbilityTest < ActiveSupport::TestCase

  def setup
    @up = user_profiles(:joes_user_profile)
    @ability = Ability.new(@user)
  end

  test "user can only read profile with personal scope set to public" do
    assert @ability.can?(:read, @up)
    @up.personal_privacy = :private
    @up.save
    refute @ability.can?(:read, @up)
  end
end

我对 Ruby 和 Rails 非常陌生。在 Ability 模型中测试 privacy_options 键值的正确方法是什么?

【问题讨论】:

    标签: ruby-on-rails ruby hash cancan


    【解决方案1】:

    替换这个:

    can :read, UserProfile, :privacy_options[:personal].eql?(:public)
    

    有了这个:

    can :read, UserProfile do |profile| 
      profile.privacy_options[:personal] == :public 
    end
    

    问题是:

    • :privacy_options[:personal] 是符号的无效语法
    • CanCan 需要选项哈希或块作为can 方法的(可选)参数(有关详细信息,请参阅Defining abilities with blocks

    附带说明,如果可能,您不应将您的隐私选项序列化为哈希 - 正如 Cancan 的文档所述,仅在加载实际记录时才使用块条件。如果您希望能够对集合设置授权,您将需要一个哈希条件(可以转换为 relation),这反过来又要求您的条件以属性为目标(或至少可以由SQL查询)

    【讨论】:

    • 太棒了!这按预期工作。我会重构一下,这样我们就不必先加载我们授权的记录。
    猜你喜欢
    • 1970-01-01
    • 2012-08-10
    • 2014-05-19
    • 2019-03-22
    • 1970-01-01
    • 2011-06-30
    • 2015-11-12
    • 2013-03-22
    相关资源
    最近更新 更多