PostgreSQL,Rails + Heroku,Column必须出现在“group by”中

时间:2011-03-28 00:19:47

标签: ruby-on-rails postgresql group-by

我在Heroku上部署应用程序时收到此错误:

Started GET "/collections/transect/search?utf8=%E2%9C%93&search%5Btagged_with%5D=village&commit=Search" for 98.201.59.6 at 2011-03-27 17:02:12 -0700

ActionView::Template::Error (PGError: ERROR:  column "photos.custom_title" must appear in the GROUP BY clause or be used in an aggregate function
: SELECT  "photos".* FROM "photos" INNER JOIN "taggings" ON "photos"."id" = "taggings"."photo_id" INNER JOIN "tags" ON "tags"."id" = "taggings"."tag_id" WHERE "tags"."name" IN ('village') AND ("photos".collection_id = 1) GROUP BY photos.id LIMIT 20 OFFSET 0):
     17: 
     18: - @bodyclass = 'dark'
     19: #search_view.photo_tiles
     20:   = render :partial => 'collections/photos/alt_tiles', :collection => @photos, :as => :photo
   app/views/collections/search.html.haml:20:in `_app_views_collections_search_html_haml__2343730670144375006_16241280__2249843891577483539'

我看到了这些类似的问题(12)。

问题是,此视图中没有任何内容要求custom_title属性,也不执行带有“group_by”子句的查询。

这是似乎触发错误的部分:

- ((photo_counter+1) % 5 == 0) ? @class = 'last' : @class = ''
.photo{ :class => @class }
  .alt_tile
    = link_to( image_tag(photo.file.url(:tile)), collection_photo_path(@collection,photo), :class => 'img_container' )
    .location= photo.location(:min)
    .tags= photo.tag_array.join(' | ')

以下是导致错误的collections#search操作:

def search
  @curator_toolbar = true
  @collection = Collection.find(params[:id])
  @search = @collection.photos.search(params[:search])
  @photos = @search.page(params[:page]).per(20)
end

所以看起来这可能是一个插件问题?我正在使用MetaSearch进行搜索功能,使用Kaminari进行分页。有没有人有任何想法或建议,具体是什么原因以及如何解决这个问题?

- 编辑 -

好的,我似乎找到了真正的问题:

将MetaSearch与我的关键字标签模型结合使用,我创建了一个如下所示的搜索方法:

def self.tagged_with( string )
  array = string.split(',').map{ |s| s.lstrip }
  joins(:tags).where('tags.name' => array ).group('photos.id')
end

现在,我在创建这个方法时获得了很多帮助 - 正如我之前提到的那样,我是一个完整的SQL白痴。

此方法适用于SQLite,但不适用于PostgreSQL,因为只要搜索中包含关键字,就会触发“group_by”问题。

所以,在this question中,它似乎表明我需要将属于我的照片模型的每一列放在“group”参数中,否则Postgre将会中断。

因为以下几个原因让我感到恐惧:

  1. 我的照片模型相当复杂,有很多字段。
  2. 我的应用程序仍处于开发阶段,照片模型的变化比其他任何更多。
  3. 如果他们忘记将列添加到标记搜索参数的group语句中,我不希望每次有人触摸照片模型时都会破坏我的代码。
  4. 所以,任何人都可以帮助我理解如何重写此方法,以便它不会破坏PostgreSQL - 理想情况下,我不必在解决方案中包含属于此模型的所有字段的列表,或者至少不是手动维护的列表?

1 个答案:

答案 0 :(得分:1)

所以,事实证明我可以通过在我的tagged_with方法中用“select”替换“group”来解决这个问题。

def self.tagged_with( string )
  array = string.split(',').map{ |s| s.lstrip }
  select('distinct photos.*').joins(:tags).where('tags.name' => array )
end

问题解决了! 请参阅这篇文章以获得一个很好的解释,为什么这是一个更好的想法。(对不起,网站后来删除了,我不记得它说了什么。)另外,感谢{{ 3}}关于解决我问题的衍生问题的答案。