CanCanCan displays localised flash messages if a resource is not authorised.
https://github.com/CanCanCommunity/cancancan/wiki/Translations-(i18n)
# en.yml
en:
unauthorized:
manage:
all: "You do not have access to %{action} %{subject}!"
I have dug through the GitHub repo, but I can't figure out how the subject
variable is defined.
From the output, I would guess that subject
is defined as something like object.class.name.underscore
.
I want to alter this to use object.model_name.human
.
This would make it much more consistent with Rails conventions, and easier to localize.
en:
activerecord:
models:
mymodel: MyLocalizedSubjectName
Can someone point me to code that defines subject
, or suggest how I can patch CanCanCan to use localized model names?
It looks to me like the message is coming from the unauthorized_message
method in ability.rb
. In particular these lines:
variables[:subject] = (subject.class == Class ? subject : subject.class).to_s.underscore.humanize.downcase
message = I18n.translate(keys.shift, variables.merge(scope: :unauthorized, default: keys + ['']))
So you could redefine that method to do what you want (although it is already using humanize
).
EDIT: Including a note about i18n keys when using human
and namespaced models. Given a locale file like this:
en:
activerecord:
models:
user: xxxx
base: aaaa
activerecord/base: bbbb
active_record/base: cccc
I get these results:
2.4.1 :001 > User.model_name.human
=> "xxxx"
2.4.1 :002 > ActiveRecord::Base.model_name.human
=> "cccc"
2.4.1 :003 >
You can also say ActiveRecord::Base.model_name.i18n_key
to avoid some trial-and-error.