]> source.dussan.org Git - redmine.git/commitdiff
Perf: use a custom decoder for Role#permissions instead of YAML.load.
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Thu, 5 Jul 2012 13:04:38 +0000 (13:04 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Thu, 5 Jul 2012 13:04:38 +0000 (13:04 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@9916 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/role.rb
test/unit/role_test.rb

index c8a1028da1eca1352fb16974431d46b349d64f04..8e8737afb0f74744b35b96669fc2d3e37d5ef497 100644 (file)
 # 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)
index 2ef20f4d57af4f41e0b2e56359bf838ae2aae770..5a1c96471d8b0058cb11771cb74e3deb0914354d 100644 (file)
@@ -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