Incompatibility with Rails 6.1+ and validations containing procs/lambdas
sundling opened this issue · 0 comments
I am not sure if this is the correct place for this issue but I found an older issue that looks similar to my problem.
Rails have passed the ActiveRecord instance to I18n.translate
for some time (added for v5.0+, added for v6.1+) to be able to support procs/lambdas and it worked fine when the errors were just plain objects.
Rails v6.1 added ActiveModel::Error and that made things a little bit more complex.
An instance of I18n::MissingTranslation
is created each time that a translation key is missing. It is initialized with locale, key and the options originally passed to I18n.translate
, including the ActiveRecord instance.
So far everything is working as expected.
The problem arises when adding caching to the application using I18n.cache_store=
. We now need to be able to serialize what we have "translated" and that is not always possible.
Is there a special reason for storing the options in the I18n::MissingTranslation
object? (Haven't lookups & interpolations been performed by that time?)
If they could be excluded it would save some bytes in the cache, especially if there are ActiveRecord objects there.
What I expected to happen
The I18n::MissingTranslation
object should be serialized successfully.
What actually happened
Exception TypeError: no _dump_data is defined for class Proc
is thrown during serialization (by Marshal.dump)
Versions of i18n, rails, and anything else you think is necessary
i18n: 1.8.10
rails: 6.1.4.1
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "activerecord", "6.1.4.1"
gem "i18n", "1.8.10"
gem "sqlite3"
end
require "active_record"
require "minitest/autorun"
require "logger"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
I18n::Backend::Simple.send(:include, I18n::Backend::Cache)
I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
ActiveRecord::Schema.define do
create_table :posts, force: true do |t|
t.string :title
end
end
class Post < ActiveRecord::Base
validates :title, length: { minimum: 10 }, if: -> { true }
def my_method
true
end
end
class BugTest < Minitest::Test
def test_run
post = Post.new(title: "My post")
post.save
assert_equal "Title is too short (minimum is 10 characters)", post.errors.first.full_message
end
end