janko / rodauth-rails

Rails integration for Rodauth authentication framework
https://github.com/jeremyevans/rodauth
MIT License
571 stars 40 forks source link

Translating the flash method on Rodauth::InternalRequestError #99

Closed woller closed 2 years ago

woller commented 2 years ago

In the app I am currently building, I have admins, who can create users (called employees in the app). They do this through an internal request. When someone tries to create a user with an already used email, a Rodauth::InternalRequestError is raised. I want to use this error to show a flash message explaining what happened. Rodauth::InternalRequestError has a flash method, but I cannot figure out how to translate it in a good way (or if this is bad practice). When I inspect the error it looks like this:

#<Rodauth::InternalRequestError: translation missing: da.rodauth.create_account_error_flash (already_an_account_with_this_login, {"login"=>"invalid login, translation missing: da.rodauth.already_an_account_with_this_login_message"})>

This looked promising, but I couldn't find a way to interpolate any values in the da.rodauth.create_account_error_flash translation. Are there any keys for this or should I find another way to do this?

Thanks!

janko commented 2 years ago

It seems like you're using the rodauth-i18n gem, and that the current locale at the time of the internal request is set to da. Were you able to translate this by adding the corresponding da.rodauth.* translation in config/locales/rodauth.da.yml, matching the default english text?

janko commented 2 years ago

Here is a self-contained example demonstrating how you'd configure I18n translations and construct a flash message for the user:

require "rodauth"
require "sequel"
require "i18n"

DB = Sequel.sqlite
DB.create_table :accounts do
  primary_key :id
  String :status_id, null: false, default: 1
  String :email, null: false, index: { unique: true, where: { status_id: [1, 2] } }
  String :password_hash
end

I18n.available_locales = :en
# you'd obviously use YAML files, this is just for demonstration purposes
I18n.backend.store_translations(:en, {
  rodauth: {
    create_account_error_flash: "Create account failed",
    already_an_account_with_this_login_message: "email already taken",
  }
})

rodauth = Rodauth.lib do
  enable :create_account
  account_password_hash_column :password_hash
  translate { |key, default| I18n.translate(key, scope: "rodauth") }
  login_does_not_meet_requirements_message do
    "invalid email#{" – #{login_requirement_message}" if login_requirement_message}"
  end
end

rodauth.create_account(login: "user@example.com", password: "secret")

begin
  rodauth.create_account(login: "user@example.com", password: "secret")
rescue Rodauth::InternalRequestError => e
  "#{e.flash} (#{e.field_errors.values.join(", ")})" #=> "Create account failed (invalid email – email already taken)"
end

Does that help?

janko commented 2 years ago

Since this doesn't seem to be bug in rodauth-rails, I will move this to discussions.