【问题标题】:Join tables with Ruby on Rails 5使用 Ruby on Rails 5 连接表
【发布时间】:2018-03-26 16:49:45
【问题描述】:

我有模型ArticleLanguage(表articleslanguages)。 文章has_many languages 和语言belongs_to article。 我想用他们的语言选择文章。 我在Article 模型中使用它:

def self.articles_per_page(limit, offset)
  joins("LEFT JOIN languages ON languages.article_id = articles.id")
  .select('articles.id, languages.language, COUNT(languages.id) as all_languages')
  .limit(limit).offset(offset)
  .group('articles.id, languages.language')
end

articles_controller

def get_per_page
  limit = 40
  render json: Article.articles_per_page(limit, params[:offset])
end

然后我发出Ajax 请求以获取JSON 的文章及其语言的响应:

$.get(articlesUrl + '?offset=' + offset, function(article){
    $.each(article, function(index, performance){
        $('#articleTable').append(// DATA //);
    });
            offset = $('#articleTable').children('.articleRow').length;
        })

问题是,如果我在 articles 表中有 1 篇文章,并且在语言表中与这篇文章关联的示例 3 种语言,它会返回 3 行与同一篇文章。

【问题讨论】:

  • 所以在你获得这个活动记录关联之后,你希望它在某些视图中呈现,对吗?
  • 是的。我在控制器@articles = Article.articles_per_page(20, 0)中调用这个方法,然后在视图中使用它。
  • 一种语言如何属于一篇文章?没有文章使用相同的语言?
  • 另一个问题。您的查询按文章和语言分组,因此如果同一文章有 3 种语言,它显然会返回 3 行。你真的想用这个查询返回什么?
  • Lmao 我 2 岁的孩子在我吃午饭时不知何故发布了一个答案。视图是什么样的?你的select()group() 的目的是什么?

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 ruby-on-rails-3.2


【解决方案1】:

考虑到您写了“我想选择带有他们语言的文章”。您可以简单地编写该类方法,例如:

def self.articles_per_page(limit, offset)
  includes(:languages).limit(limit).offset(offset)
end

@articles = Article.articles_per_page(10, 0)

= @articles.each do |article|
  = article.whatever
  = article.languages.each do |language|
    = language.whatever
  = article.languages.count # I'd add counter_cache

如果您只需要 count() 我会在文章模型中添加一个 counter_cache 列:

在语言.rb中

belongs_to :article, counter_cache: true

然后将languages_count 添加到文章模型中,您可以执行以下操作:

= @articles.each do |article|
  = article.languages_count

但是,对于您的选择和组,我假设您可能正在尝试为您的查询添加某种性能?如果是这种情况,了解您的视图是什么样的以及选择/组组合的用途会有所帮助。

【讨论】:

  • 您好,感谢您的回答。问题已编辑。我正在使用该查询,因为我使用 Ajax 来获取带有文章及其语言的 JSON response
  • 我的意思是他们的语言。
  • 我觉得计数器缓存应该有助于解决您的问题。您只需要修改任何前端 js 即可使用新的 json 对象。你知道你的视图期望什么 json 能正常工作吗?
【解决方案2】:

我知道问题是因为我使用的是.group(articles.id, languages.language, ..),但没有它我会收到错误:

Mysql2::Error: 在没有 GROUP BY 的聚合查询中,SELECT 列表的表达式 #1 包含非聚合列 '.articles.id';这与 sql_mode=only_full_group_by 不兼容:

我所做的是删除group(...)config/database.yml

default: &default
    adapter: mysql2
    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
    timeout: 5000
    username: database_user
    password: database_password
    variables:
        sql_mode: TRADITIONAL # THIS FIX THE PROBLEM

然后重启服务器。

【讨论】:

    猜你喜欢
    • 2011-05-10
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多