-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Translated slugs not generated #10
Comments
After some digging, it seems that it's not yet a feature. The implementation is not exactly the same as friendly_id-globalize : current : https://github.com/shioyama/friendly_id-mobility/blob/master/lib/friendly_id/mobility.rb#L44 |
Hmm I don't see anything obvoiusly wrong with your setup. The last thing you noticed when trying to force slug regeneration is triggering Mobility to destroy the blank translations (that's why you see the It would help if you could figure out if this is an issue specific to slugs or whether you can reproduce it without friendly_id-mobility. I think this should work in general: class Post < ApplicationRecord
extend Mobility
translates :title, locale_accessors: true
end
Mobility.locale = :en
post = Post.create(title: "foo")
post.title_en
#=> "foo"
post.title_ja = "foo ja"
post.title_de = "foo de"
post.save
post = Post.first
post.title_en
#=> "foo"
post.title_ja
#=> "foo ja"
post.title_de
#=> "foo de" Just tried this on 0.7.5 and it works fine AFAICT (and I'm pretty sure tests would fail if it did not). |
I'm writing a standalone test suite |
Oh sorry missed your other comment, reading up now. |
#!/usr/bin/env ruby
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
gem 'rails', '5.1.6'
gem 'sqlite3'
gem 'mobility'
gem 'friendly_id'
gem 'friendly_id-mobility'
gem 'database_cleaner'
end
require 'active_record'
require 'minitest/autorun'
require 'logger'
require 'database_cleaner'
# Ensure backward compatibility with Minitest 4
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)
I18n.config.available_locales = [:fr, :en, :es, :pt]
I18n.default_locale = :fr
Mobility.configure do |config|
config.default_backend = :table
config.accessor_method = :translates
config.query_method = :i18n
config.default_options[:dirty] = true
config.default_options[:locale_accessors] = true
end
ActiveRecord::Schema.define do
create_table :posts, force: true do |t|
end
create_table :post_translations, force: :cascade do |t|
t.string :slug
t.string :title
t.text :content
t.string :locale, null: false
t.integer :post_id, null: false
t.datetime :created_at, null: false
t.datetime :updated_at, null: false
t.index ["locale"], name: "index_post_translations_on_locale"
t.index ["post_id", "locale"], name: "index_post_translations_on_post_id_and_locale", unique: true
t.index ["post_id"], name: "index_post_translations_on_post_id"
end
end
class Post < ActiveRecord::Base
# Translations
extend Mobility
translates :slug, :title, :content, fallbacks: { en: [:fr], pt: [:es, :fr] }
# FriendlyId
extend FriendlyId
friendly_id :title, use: :mobility
# Uncomment to make tests pass
# def should_generate_new_friendly_id?
# translation_for(::Mobility.locale).send(friendly_id_config.slug_column).nil?
# end
# def translation_for(locale)
# translation = translations.in_locale(locale)
# translation ||= translations.build(locale: locale)
# translation
# end
# def set_slug(normalized_slug = nil)
# super
# changed.each do |change|
# if change =~ /\A(?:#{friendly_id_config.base}|#{friendly_id_config.slug_column})_([a-z]{2}(_[a-z]{2})?)/
# locale, suffix = $1.split('_'.freeze)
# locale = "#{locale}-#{suffix.upcase}".freeze if suffix
# ::Mobility.with_locale(locale) { super }
# end
# end
# end
end
class BugTest < Minitest::Test
extend Minitest::Spec::DSL
before :each do
DatabaseCleaner.start
end
after :each do
DatabaseCleaner.clean
end
def test_slug_generation
post = Post.new(title_fr: 'Titre français', title_es: 'Título español', title_en: 'English title')
post.save
# Here what I expect :
assert_equal('titre-francais', post.slug_fr) # this one pass
assert_equal('titulo-espanol', post.slug_es) # this one doesn't
assert_equal('english-title', post.slug_en) # neither this one
assert_nil post.slug_pt # normal, we didn't provide any value
post
end
def test_slug_regeneration
# Create post
post = test_slug_generation
# Reset slug post
post.slug_fr = nil
post.slug_es = nil
post.save
# Here what I expect :
assert_equal('titre-francais', post.slug_fr) # this one pass
assert_equal('titulo-espanol', post.slug_es) # this one doesn't
end
end |
I think I found the culprit :) |
|
Nice catch! Would you like to make a PR to fix it? 😉 Or even just a failing spec would be great. |
Sure :) Do you have an equivalent of |
I found https://github.com/shioyama/mobility/blob/master/lib/mobility/backends/active_record/table.rb#L287 but got an error : |
Yeah, there is an equivalent but you can't use it since it's specific to the table backend. I'll have a look later but you'll need to use the generic interface, otherwise the change will break any other backend. |
Ok. For now it works as expected if I add this to the model : class Post < ActiveRecord::Base
....
def should_generate_new_friendly_id?
translation_for(::Mobility.locale).send(friendly_id_config.slug_column).nil?
end
def translation_for(locale)
translation = translations.in_locale(locale)
translation ||= translations.build(locale: locale)
translation
end
end |
Yes, that works but it won't work a general solution unfortunately. This is the challenge of Mobility 😉 I'll have a look later. |
Yes I understand. For now I can live with this small patch and go ahead to finalize the migration to this awesome gem :) |
Do you think you could create a failing spec? Then I think I can fix this. |
Hi there! I also found a bug in def test_slug_regeneration
post = Post.new(title_fr: 'Titre français', title_es: 'Título español', title_en: 'English title')
post.save
post.slug_fr = nil
post.slug_es = nil
post.save
# Here what I expect :
assert_equal('titre-francais', post.slug_fr) # this one pass
assert_equal('titulo-espanol', post.slug_es) # this one doesn't
end I had to override def set_slug(normalized_slug = nil)
super
changed.each do |change|
if change =~ /\A#{friendly_id_config.base}_([a-z]{2}(_[a-z]{2})?)/ || change =~ /\A#{friendly_id_config.slug_column}_([a-z]{2}(_[a-z]{2})?)/
locale, suffix = $1.split('_'.freeze)
locale = "#{locale}-#{suffix.upcase}".freeze if suffix
::Mobility.with_locale(locale) { super }
end
end
end |
I added a test in #12 but it's passing for me locally, can you have a look? |
Oh never mind, seems to be failing on Travis. |
Ah ok, I wasn't running the spec correctly locally. So the spec identifies the issue. I'll try adding your fix 😄 |
Hi there!
I'm migrating from Globalize to Mobility. I'm also using FriendlyID on some models so I'm migrating from friendly_id-globalize to friendly_id-mobility too.
I've followed the migration tutorial and almost everything works so far, except one thing : translated slugs are not generated.
The slug for the current locale (fr) is well generated and saved, but the slugs for other locales are not generated.
Here my setup taken from the README :
When I set all
title_*
fields, it only generates thefr
slug.I also tried to force slug regeneration as in the FriendlyID doc but got some strange results :
the SQL output :
It's not an issue with strong params since all
title_*
are persisted.As I said, the only issue is that
slug_es
(and friends :en
,pt
) are never generated, only the current locale.I don't know if it's a bug or if I missed something in the configuration but I can't finalize the migration without this feature.
Thanks for your help!
The text was updated successfully, but these errors were encountered: