Skip to content

Update cancancan 3.6.1 → 3.7.0 (minor) - #1949

Open
depfu[bot] wants to merge 1 commit into
masterfrom
depfu/update/cancancan-3.7.0
Open

depfu[bot] wants to merge 1 commit into
masterfrom
depfu/update/cancancan-3.7.0

Conversation

@depfu

@depfu depfu Bot commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Here is everything you need to know about this update. Please take a good look at what changed and the test results before merging this pull request.

What changed?

✳️ cancancan (3.6.1 → 3.7.0) · Repo · Changelog

Release Notes

3.7.0

The one below is a list of all the PRs merged. For a more detailed update, read the blog post about this release.

  • Merge the ControllerResourceLoader, ControllerResourceBuilder, ControllerResourceFinder, ControllerResourceNameFinder and ControllerResourceSanitizer modules into CanCan::ControllerResource, and call the params method of the controller only once per request: it was called once more for every attribute set by the conditions of the ability. WARNING: the five modules no longer exist; override their methods in a subclass of CanCan::ControllerResource instead. (@coorasse)
  • Expand the actions again after alias_action, clear_aliased_actions and merge: can? kept using the aliases expanded by a previous check, so clear_aliased_actions did not remove can :read from can?(:index, Model). (@coorasse)
  • Raise an error when an action is aliased to :manage, which granted every action, or to itself, which looped forever. (@coorasse)
  • Do not include the primary key in permitted_attributes for a rule without attributes, remove every attribute with a cannot rule without attributes, including those that are not columns, and accept a hash subject instead of raising a TypeError. WARNING: permitted_attributes no longer returns :id, and with a composite primary key none of its columns are returned. (@coorasse)
  • Convert a String resource name to a symbol in load_and_authorize_resource and the skip_* methods: load_and_authorize_resource 'article' treated the resource as a parent and authorized :show on the class instead of the action on the record. (@coorasse)
  • #927: Look up the unauthorized message of a String action through its aliases: authorize!('index', post) did not use the message defined for read. (@coorasse)
  • #913: Match a symbol in a condition with the string that has the same name in can?, as accessible_by already did: cannot :read, Post, state: :draft on a string column no longer allows can?(:read, draft). WARNING: a can rule with a symbol now also allows records whose string attribute has the same name. (@bruno-costanzo)
  • #905: Match String actions like Symbol actions: can?('destroy', user) ignored cannot :destroy, User when can :manage was defined, and skip_authorize_resource except: 'destroy' also skipped the authorization of destroy. WARNING: a String action now goes through the aliases like a Symbol action, so can?('show', order) and authorize!(action_name, order) are allowed by can :read, Order and may grant access that 3.6 denied. A rule defined with a String action now matches the same Symbol action, permissions returns symbols, and a block rule without a subject receives the action as a symbol. (@bruno-costanzo)
  • #848: Do not deny can?(:index, parent => Model) because of a cannot rule with conditions on the model, as can?(:index, Model) already did: load_and_authorize_resource failed on the index of a nested resource. (@coorasse)
  • #861, #846, #690: Give the conditions of accessible_by the table aliases that Active Record gives to the joined associations, and build them with the model of each table. A rule with a has_many :through association, or with an association without conditions, used the alias of another table: the query failed or returned the wrong records. On an aliased table, a model was not converted to its foreign key and the values were not cast with the attribute types of the model. (@coorasse)
  • #911: Load the resource when the id is only whitespace: a request like /books/%20 ran the action with a nil resource, authorized only against the class, instead of raising ActiveRecord::RecordNotFound. (@bruno-costanzo)
  • #833: Match nil in an array of enum values in can?, as accessible_by already did: can :read, Post, status: [nil, :published] now allows a post without a status. (@jtagle2, @coorasse)
  • #910: Accept a subclass of CanCan::ModelAdapters::Strategies::Base as accessible_by_strategy, so the SQL generated by accessible_by can be customized with your own strategy. (@cb341, @coorasse)
  • #909: Make can? and accessible_by consistent for cannot rules and single table inheritance: a cannot rule on a subclass keeps its precedence in accessible_by, records with NULL in a column of a cannot condition are no longer excluded, rules on subclasses of subclasses reach the base class, and a class check passes when the class or any of its subclasses is allowed. WARNING: accessible_by returns more records when a cannot rule has conditions on a nullable column, and can? on an STI base class no longer fails because a subclass is forbidden. (@coorasse, @0llirocks, @kevinluo201)
  • #880: Fix accessible_by with rules on STI subclasses: a rule on a subclass without conditions no longer discards the rules defined before it, and rules with the same conditions on different subjects are no longer compressed into one. (@takayamaki, @sjoulbak)
  • #890: Support an Active Record relation as the value of a condition in can?: the selected column, or the primary key, is checked with a query, as accessible_by already did. (@olistik)
  • #908: Join consecutive can rules in a flat chain of ORs in the SQL conditions, so that many rules on the same model no longer overflow the parser of SQLite. (@coorasse)
  • #907: Make with_accessible_by_strategy thread safe: the strategy chosen in the block no longer leaks into concurrent requests. (@NikosVlagoidis, @coorasse)
  • #906: Keep the conditions of an association when a rule is a scope: group.posts.accessible_by(ability) returned the posts of every group matched by the scope. WARNING: accessible_by called on an association now returns fewer records when the scope of a rule constrains the same column as the association. Only the conditions dropped by merge are applied again, so a condition on a subquery like where(category: Category.where(...)) is not turned into IS NULL, and the conditions of a default scope removed by unscope in the rule stay removed. (@coorasse)
  • #694: Document that cannot supports the :all subject. (@jaredbeck)
  • #852: Add changelog_uri to the gemspec, so rubygems.org links to the changelog. (@mark-young-atg)
  • #842: Add disallowed_attributes to retrieve the attributes forbidden by cannot rules. (@mswiszcz)
  • #904: Assign the parent of a singleton resource through the inverse of the association when the resource has no setter named after the through option. (@coorasse)
  • #878: Support through_association together with singleton when loading a resource. (@cgunther)
  • #786: Fix the table aliases generated by accessible_by when the same association is joined more than twice: the WHERE clause referenced an alias that was never joined. (@daveallie)
  • #902: Do not change the rules of the ability in accessible_by: a rule shared by several models kept the conditions normalized for the first queried model. (@bruno-costanzo)
  • #901: Keep the scope of a has_many :through association in accessible_by: the association was rewritten into its through and source associations and its scope was dropped, so accessible_by returned records that can? denies. WARNING: accessible_by returns fewer records for a rule on a has_many :through association with a scope. (@bruno-costanzo)
  • Remove the VitePress documentation website: the documentation lives in the docs folder as plain Markdown. (@coorasse)

3.6.2

  • #898: Do not share cancan_skipper between controller subclasses: skip_authorize_resource and skip_load_resource in a subclass no longer apply to the superclass or sibling controllers. (@bruno-costanzo)
  • #894: Use lease_connection instead of the deprecated connection on Rails 7.2+. (@benaitcheson)

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.


Depfu Status

Depfu will automatically keep this PR conflict-free, as long as you don't add any commits to this branch yourself. You can also trigger a rebase manually by commenting with @depfu rebase.

All Depfu comment commands
@​depfu rebase
Rebases against your default branch and redoes this update
@​depfu recreate
Recreates this PR, overwriting any edits that you've made to it
@​depfu merge
Merges this PR once your tests are passing and conflicts are resolved
@​depfu cancel merge
Cancels automatic merging of this PR
@​depfu close
Closes this PR and deletes the branch
@​depfu reopen
Restores the branch and reopens this PR (if it's closed)
@​depfu pause
Ignores all future updates for this dependency and closes this PR
@​depfu pause [minor|major]
Ignores all future minor/major updates for this dependency and closes this PR
@​depfu resume
Future versions of this dependency will create PRs again (leaves this PR as is)

@depfu depfu Bot added the depfu label Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants