(While this discusses Blacklight engine, I believe the question is actually purely about Rails.)
Continuing my quest from scope
around mount
ineffective? (tl;dr: make the engine routes obey the same :locale
scope as application routes), after digging through Rails source.
Currently, I have this setup:
# config/routes.rb
Rails.application.routes.draw do
Blacklight::Engine.routes.default_scope = { path: "(:locale)", locale: /en|ja/ }
mount Blacklight::Engine => '/'
scope "(:locale)", locale: /en|ja/ do
# ...
end
end
This makes the routes work properly. However, I had this view code to generate the alternate-language links to the current page (guided by link_to the current page plus/merged with a param [duplicate]):
<div id="languages_nav_popup" class="navbar-inverse">
<% locales.each do |locale| %>
<% next if locale == I18n.locale %>
<%= link_to params.permit!.merge(locale: locale) do %>
<img src="<%= url_for "/img/flag/#{locale}.png" %>"/>
<% end %>
<% end %>
</div>
That link_to
fails when the current page is an Engine route. This is due to this piece of code in actionpack
:
# lib/action_dispatch/journey/formatter.rb
# Skip this route unless a name has been provided or it is a
# standard Rails route since we can't determine whether an options
# hash passed to url_for matches a Rack application or a redirect.
next unless name || route.dispatcher?
With link_to options, &block
syntax that I use above, name
is nil
; and dispatcher?
is false
for an engine route. (If I pass that check by inserting a name by force, I get a nonsensical URL like .../assets?action=index&controller=saved_searches&locale=ja
).
I'm getting desperate here, almost to the point where I'm thinking the best way to deal with this is regexp. This atrocity works:
<%= link_to request.base_url + request.original_fullpath.sub(%r{(?<=/)#{I18n.locale}}, locale.to_s) do %
Is there no way to generate the correct URL properly?