diff --git a/app/models/role.rb b/app/models/role.rb index c8a1028da..8e8737afb 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -16,6 +16,19 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class Role < ActiveRecord::Base + # Custom coder for the permissions attribute that should be an + # array of symbols. Rails 3 uses Psych which can be *unbelievably* + # slow on some platforms (eg. mingw32). + class PermissionsAttributeCoder + def self.load(str) + str.to_s.scan(/:([a-z0-9_]+)/).flatten.map(&:to_sym) + end + + def self.dump(value) + YAML.dump(value) + end + end + # Built-in roles BUILTIN_NON_MEMBER = 1 BUILTIN_ANONYMOUS = 2 @@ -44,7 +57,7 @@ class Role < ActiveRecord::Base has_many :members, :through => :member_roles acts_as_list - serialize :permissions, Array + serialize :permissions, ::Role::PermissionsAttributeCoder attr_protected :builtin validates_presence_of :name @@ -54,10 +67,6 @@ class Role < ActiveRecord::Base :in => ISSUES_VISIBILITY_OPTIONS.collect(&:first), :if => lambda {|role| role.respond_to?(:issues_visibility)} - def permissions - read_attribute(:permissions) || [] - end - def permissions=(perms) perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms write_attribute(:permissions, perms) diff --git a/test/unit/role_test.rb b/test/unit/role_test.rb index 2ef20f4d5..5a1c96471 100644 --- a/test/unit/role_test.rb +++ b/test/unit/role_test.rb @@ -44,6 +44,11 @@ class RoleTest < ActiveSupport::TestCase assert_equal 90, target.workflows.size end + def test_permissions_should_be_unserialized_with_its_coder + Role::PermissionsAttributeCoder.expects(:load).once + Role.find(1).permissions + end + def test_add_permission role = Role.find(1) size = role.permissions.size