Perf: use a custom decoder for Role#permissions instead of YAML.load.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@9916 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang 2012-07-05 13:04:38 +00:00
parent cc2ee90f97
commit a1f17b982c
2 changed files with 19 additions and 5 deletions

View File

@ -16,6 +16,19 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Role < ActiveRecord::Base 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 # Built-in roles
BUILTIN_NON_MEMBER = 1 BUILTIN_NON_MEMBER = 1
BUILTIN_ANONYMOUS = 2 BUILTIN_ANONYMOUS = 2
@ -44,7 +57,7 @@ class Role < ActiveRecord::Base
has_many :members, :through => :member_roles has_many :members, :through => :member_roles
acts_as_list acts_as_list
serialize :permissions, Array serialize :permissions, ::Role::PermissionsAttributeCoder
attr_protected :builtin attr_protected :builtin
validates_presence_of :name validates_presence_of :name
@ -54,10 +67,6 @@ class Role < ActiveRecord::Base
:in => ISSUES_VISIBILITY_OPTIONS.collect(&:first), :in => ISSUES_VISIBILITY_OPTIONS.collect(&:first),
:if => lambda {|role| role.respond_to?(:issues_visibility)} :if => lambda {|role| role.respond_to?(:issues_visibility)}
def permissions
read_attribute(:permissions) || []
end
def permissions=(perms) def permissions=(perms)
perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms
write_attribute(:permissions, perms) write_attribute(:permissions, perms)

View File

@ -44,6 +44,11 @@ class RoleTest < ActiveSupport::TestCase
assert_equal 90, target.workflows.size assert_equal 90, target.workflows.size
end end
def test_permissions_should_be_unserialized_with_its_coder
Role::PermissionsAttributeCoder.expects(:load).once
Role.find(1).permissions
end
def test_add_permission def test_add_permission
role = Role.find(1) role = Role.find(1)
size = role.permissions.size size = role.permissions.size