Issue with non-translatable models
Closed this issue · 1 comments
Gem version: friendly_id-globalize (~> 1.0.0.alpha3)
Ruby version: 2.3.0
Rails version: 5.1
I'm making use of the :history
plugin in a bunch of translatable models but also in a couple of non-translatable models like User
.
class User < ApplicationRecord
extend FriendlyId
friendly_id :full_name, use: [:slugged, :history]
...
end
For some reason my User model responds to :translations
which causes the friendly_id-globalize
to take over the history functionality. I needed to patch a few finder methods to make it work.
Instead of respond_to?(:translations)
it is better to use respond_to?(:translation_class)
.
I also found the need to override the create_slug
method to check if the model is making use of Globalize.
You might want to change the exists_by_friendly_id?(id)
method too because you are calling "super" on a non existing method. Because the Finder methods are included, they cannot be called with "super" and you must copy the method over from the original gem. You did it for create_slug
but forgot to do it for exists_by_friendly_id?(id)
People who are having the same issues can add this monkey patch to their initializers untill the issues are fixed:
module FriendlyId
module History
module FinderMethods
include ::FriendlyId::FinderMethods
def exists_by_friendly_id?(id)
if respond_to?(:translation_class)
joins(:slugs, :translations).where(translation_class.arel_table[friendly_id_config.query_field].eq(id)).exists? || joins(:slugs).where(slug_history_clause(id)).exists?
else
joins(:slugs).where(slug_history_clause(id)).exists?
end
end
def slug_history_clause(id)
if respond_to?(:translation_class)
Slug.arel_table[:sluggable_type].eq(base_class.to_s).and(Slug.arel_table[:slug].eq(id)).and(Slug.arel_table[:locale].eq(::Globalize.locale))
else
Slug.arel_table[:sluggable_type].eq(base_class.to_s).and(Slug.arel_table[:slug].eq(id))
end
end
end
def create_slug
if respond_to?(:translation_class)
translations.map(&:locale).each do |locale|
::Globalize.with_locale(locale) {super_create_slug(locale)}
end
else
super_create_slug(nil)
end
end
end
end
Thanks for your code @jefvlamings
I need to pass my current location on super_create_slug
because locale
is mandatory on the table:
super_create_slug(current_locale)