{"action":"created","issue":{"url":"https://api.github.com/repos/CanCanCommunity/cancancan/issues/291","labels_url":"https://api.github.com/repos/CanCanCommunity/cancancan/issues/291/labels{/name}","comments_url":"https://api.github.com/repos/CanCanCommunity/cancancan/issues/291/comments","events_url":"https://api.github.com/repos/CanCanCommunity/cancancan/issues/291/events","html_url":"https://github.com/CanCanCommunity/cancancan/issues/291","id":129204521,"number":291,"title":"Why would multiple merge calls behave non-deterministically?","user":{"login":"Fritzinger","id":1541595,"avatar_url":"https://avatars.githubusercontent.com/u/1541595?v=3","gravatar_id":"","url":"https://api.github.com/users/Fritzinger","html_url":"https://github.com/Fritzinger","followers_url":"https://api.github.com/users/Fritzinger/followers","following_url":"https://api.github.com/users/Fritzinger/following{/other_user}","gists_url":"https://api.github.com/users/Fritzinger/gists{/gist_id}","starred_url":"https://api.github.com/users/Fritzinger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Fritzinger/subscriptions","organizations_url":"https://api.github.com/users/Fritzinger/orgs","repos_url":"https://api.github.com/users/Fritzinger/repos","events_url":"https://api.github.com/users/Fritzinger/events{/privacy}","received_events_url":"https://api.github.com/users/Fritzinger/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-01-27T16:52:48Z","updated_at":"2016-01-27T22:07:14Z","closed_at":null,"body":"Is it frowned upon to have multiple merge calls duping rules from multiple CanCan::Ability classes in a single Ability.initialize?\r\n\r\nAs with so many other CanCan users, `Ability.rb`  has become large and unwieldy so I'm trying to split it up:\r\n\r\n    def intialize\r\n      self.merge(Abilities::ModelA.new(user))\r\n      self.merge(Abilities::ModelC.new(user))\r\n      ...\r\n      # other rules not covered in separate files\r\n      can? :do_something_else, ModelZ if user.subscriber?\r\n    end\r\n\r\nHowever, this is producing sporadic failures in my test.\r\n\r\nI'll note that in examples I've seen elsewhere on the web, e.g. [here][1], only one ability seems to be merged:\r\n\r\n    if user.admin?\r\n      self.merge(AdminAbility.new(user))\r\n    else\r\n      self.merge(NormalAbility.new(user))\r\n    end\r\n\r\nHowever, I can't do it this way. In our SAAS app, permissions are determined not by role but rather whether a user is linked to a record, or an \"associate\" of another subscriber who has that record:\r\n\r\n    can? :manage, ModelA, do |model_a|\r\n      user.model_a_collection.include? model_a || user.associate_for? model_a\r\n    end\r\n\r\nAgain, user permissions cannot be determined by a simple role check, every rule for every model has to be checked for every user.\r\n\r\nSimple expectations like the following are failing at least one time in ten, and much more if I run them more times, e.g. 15/30 times:\r\n\r\n    expect(user).to have_ability([:destroy, :update], for: modelA)\r\n\r\n    Failure/Error: expect(user).to have_ability([:destroy, :update], for: flyer)\r\n           expected User:#<User:0x007ff876e16cb8> to have ability:{:destroy=>true, :update=>true} for #<ModelA:0x007ff876a44c48>, but actual result is {:destroy=>false, :update=>false}\r\n\r\nThis looks like those rules are simply not being defined sometimes and I'm wondering if there is some weird resource constraint or something that would make multiple merges not play nicely together.\r\n\r\n  [1]: http://stackoverflow.com/a/25163285/160604"},"comment":{"url":"https://api.github.com/repos/CanCanCommunity/cancancan/issues/comments/175885119","html_url":"https://github.com/CanCanCommunity/cancancan/issues/291#issuecomment-175885119","issue_url":"https://api.github.com/repos/CanCanCommunity/cancancan/issues/291","id":175885119,"user":{"login":"Fritzinger","id":1541595,"avatar_url":"https://avatars.githubusercontent.com/u/1541595?v=3","gravatar_id":"","url":"https://api.github.com/users/Fritzinger","html_url":"https://github.com/Fritzinger","followers_url":"https://api.github.com/users/Fritzinger/followers","following_url":"https://api.github.com/users/Fritzinger/following{/other_user}","gists_url":"https://api.github.com/users/Fritzinger/gists{/gist_id}","starred_url":"https://api.github.com/users/Fritzinger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Fritzinger/subscriptions","organizations_url":"https://api.github.com/users/Fritzinger/orgs","repos_url":"https://api.github.com/users/Fritzinger/repos","events_url":"https://api.github.com/users/Fritzinger/events{/privacy}","received_events_url":"https://api.github.com/users/Fritzinger/received_events","type":"User","site_admin":false},"created_at":"2016-01-27T22:07:14Z","updated_at":"2016-01-27T22:07:14Z","body":"I see the problem isn't going away when I remove all of the merge calls, so presumably they aren't the cause. It did previously for a smaller test run, I guess that was non-deterministic behaviour in action :/."}}