1

语境

考虑具有sluggable多态关系的 Rails 6 应用程序,模型的has_many本地化为不同语言的 slug 集合可以建模如下:

# slugs table schema
create_table :slugs do |t|
  t.references :sluggable, polymorphic: true
  t.string :locale, null: false
  t.string :slug, null: false
  t.timestamps null: false
end
add_index :slugs, [:locale, :slug], unique: true

# app/models/slug.rb
class Slug < ApplicationRecord
  belongs_to :sluggable, polymorphic: true
end

# app/models/post.rb
class Post < ApplicationRecord
  has_many :slugs, -> { where(locale: I18n.locale).order(created_at: :desc) }, as: :sluggable
end
 
# app/models/course.rb
class Course < ApplicationRecord
  has_many :slugs, -> { where(locale: I18n.locale).order(created_at: :desc) }, as: :sluggable
end

这应满足以下要求:

  1. A在每种语言中sluggable可以有不同的数量slugs(一种语言的 slug 和另一种语言的 slug 之间没有直接映射);
  2. 约束确保 slug 对于每个语言环境都是唯一的(sluggable_type可以包含在索引中,具体取决于是否希望 slug 在整个应用程序中唯一或在每种模型类型中唯一);
  3. 需要一个单一的连接(同时处理翻译和 slug<->post 关系);
  4. 该关系保持其顺序以允许选择“默认” slug

可以使用 查询帖子的 slug post.slugs。按照惯例,帖子的“默认”slug 是post.slugs.first.

可以通过其语言环境和 slug 找到帖子,如下所示:

Post.includes(:slugs).find_by(slugs: { "my-slug" })

问题

如何使用 Mobility 库实现等效效果?我已经在我的应用程序的其余部分中使用了这个翻译库,并且希望能够以一致的方式查询翻译的内容。

键值后端文档似乎符合要求#3,即表mobility_string_translations是一个多态关系,看起来它可以替换slugs表。然而,关于#2,它声明了一个唯一索引,["translatable_id", "translatable_type", "locale", "key"]因此它不允许给定sluggable和语言环境有多个 slug。该文档展示了如何在每个语言环境中使用单个值(例如 aPost和 a title)而不是多个值(例如 aPost和多个slugs,如上所述)翻译属性。

Mobility 是否支持上述场景,或者是否可以/应该使用某种新的后端来实现?

PS:我还打开了一个 GitHub 问题

PPS:在这个 SO question中,我还考虑了将这些 slug 存储在 JSONB 数组中的可能性,但建议不要使用,此外,Mobility只能翻译stringtext类型

4

0 回答 0