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