无法使用Mobility通过Rails中的已翻译列进行排序

此问题基于发布到Mobility GitHub项目的问题。

上下文

  • Rails :5.0.6
  • 流动性 :0.4.2(带表后端)

我正在使用支持多种文章类型的文章表(例如,博客文章,案例研究,知识库文章)。 此表包含一个列,用于跟踪查看文章的次数 – 一个整数列,每次为文章调用show动作时该列都会递增。

在实现这些文章的翻译时,我想单独跟踪每个翻译的视图数,而不是主文章对象。 为了实现这一点,我将views属性包含在我的对象的翻译属性之一:

 class Article  [:title, :subtitle, :body] has_and_belongs_to_many :products attachment :hero_image, content_type: %w(image/jpeg image/png image/gif) validates :title, :body, :posted_on, presence: true scope :current, -> { where 'posted_on  { where type: ['BlogPost', 'CaseStudy'] } def log_view(by = 1) self.views ||= 0 self.views += by self.save(touch: false) end def to_param "#{id} #{title}".parameterize end def published? posted_on < Date.tomorrow end end 

预期的行为

在我的控制器中,我想列出我查看过的十篇最受欢迎的文章:

 @top_articles = Article.current.news_articles.order(views: :desc, posted_on: :desc).limit(10) 

我希望收到一系列文章,就像我在实施Mobility之前所做的那样。

实际行为

我得到的是#

。 如果我然后尝试将其转换为@top_articles.to_a的数组,我会收到此错误:

  Article Load (0.7ms) SELECT "articles".* FROM "articles" WHERE (posted_on < '2018-02-11') AND "articles"."type" IN ('BlogPost', 'CaseStudy') ORDER BY "articles"."views" DESC, "articles"."posted_on" DESC LIMIT $1 [["LIMIT", 10]] ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column articles.views does not exist LINE 1: ...les"."type" IN ('BlogPost', 'CaseStudy') ORDER BY "articles"... ^ : SELECT "articles".* FROM "articles" WHERE (posted_on < '2018-02-11') AND "articles"."type" IN ('BlogPost', 'CaseStudy') ORDER BY "articles"."views" DESC, "articles"."posted_on" DESC LIMIT $1 from /usr/local/bundle/gems/activerecord-5.0.6/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `async_exec' 

将查询更改为包含i18n

 @top_articles = Article.i18n.current.news_articles.order(views: :desc, posted_on: :desc).limit(10) 

…返回#<#:0x286c3e0> ,当我尝试将其转换为数组时,我得到同样的结果:

  Article Load (0.7ms) SELECT "articles".* FROM "articles" WHERE (posted_on < '2018-02-11') AND "articles"."type" IN ('BlogPost', 'CaseStudy') ORDER BY "articles"."views" DESC, "articles"."posted_on" DESC LIMIT $1 [["LIMIT", 10]] ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column articles.views does not exist LINE 1: ...les"."type" IN ('BlogPost', 'CaseStudy') ORDER BY "articles"... ^ : SELECT "articles".* FROM "articles" WHERE (posted_on < '2018-02-11') AND "articles"."type" IN ('BlogPost', 'CaseStudy') ORDER BY "articles"."views" DESC, "articles"."posted_on" DESC LIMIT $1 from /usr/local/bundle/gems/activerecord-5.0.6/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `async_exec' 

事实certificate,虽然Mobility支持在where子句中使用已翻译的字段,但它目前在Active Record查询的order子句中不支持它们。

解决方法尝试

1.在order子句中引用转换表

根据gem作者的反馈,我尝试了查询:

 Article.i18n.current.news_articles.order('article_translations.views desc', 'articles.posted_on desc') 

…返回#<#>对象, to_a返回此错误:

 ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "article_translations" LINE 1: ...les"."type" IN ('BlogPost', 'CaseStudy') ORDER BY article_tr... ^ : SELECT "articles".* FROM "articles" WHERE (posted_on < '2018-02-12') AND "articles"."type" IN ('BlogPost', 'CaseStudy') ORDER BY article_translations.views desc, articles.posted_on desc LIMIT $1 from /usr/local/bundle/gems/activerecord-5.0.6/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `async_exec' 

2.为转换表添加joinsincludes子句

 Article.i18n.joins(:article_translations).order('article_translations.views desc', 'articles.posted_on desc').limit(10) 

此查询再次返回#<#>对象, to_a结果为:

 ActiveRecord::ConfigurationError: Can't join 'Article' to association named 'article_translations'; perhaps you misspelled it? from /usr/local/bundle/gems/activerecord-5.0.6/lib/active_record/associations/join_dependency.rb:231:in `find_reflection' 

3.将has_many :article_translations添加到模型中

向模型添加关系会抛出此错误:

 uninitialized constant Article::ArticleTranslation 

所以…

我接下来应该尝试什么?

UPDATE

现在支持按翻译的属性排序,版本0.8.0 /

这样做:

 Article.i18n.current.news_articles. order(:views => :desc, :'articles.posted_on' => :desc) 

和Mobility将处理所有事情(您不需要加入翻译表等)

原始答案

您是正确的,您需要加入翻译表,但该关联被命名为translations ,而不是article_translations

在任何情况下,都有一个连接转换表的join_translations方法,所以这应该工作:

 Article.i18n. current. news_articles. join_translations. order('article_translations.views desc', 'articles.posted_on desc')