PostgreSQL, Rails + Heroku, Column must appear in "group by"
I'm getting this error when I deploy my app on 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'
I saw these similar questions (1,2).
The problem is, nothing in this view is asking for the custom_title attribute, nor am I executing a query with a "group_by" clause.
Here's the partial that seems to trigger the error:
- ((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(' | ')
Here's the collections#search
action which is what raised the error:
def search
@curator_toolbar = true
@collection = Collection.find(params[:id])
@search = @collection.photos.search(params[:search])
@photos = @search.page(params[:page]).per(20)
end
So it looks like maybe this is a plugin issue? I'm using MetaSearch for search functionality and Kaminari for pagination. Does anyone have any ideas or suggestions as to what would cause this specifically and how I can possibly fix it?
--EDIT--
Ok, I seem to have found the real problem:
Using MetaSearch with my keyword tags model开发者_开发技巧, I created a search method that looks like this:
def self.tagged_with( string )
array = string.split(',').map{ |s| s.lstrip }
joins(:tags).where('tags.name' => array ).group('photos.id')
end
Now, I was given a lot of help in creating this method -- as I mentioned before I'm a total SQL moron.
This method works on SQLite but not on PostgreSQL because whenever keywords are included in a search it triggers the "group_by" problem.
So, in this question it seems to indicate that I need to put every column that is part of my photo model in the "group" argument or Postgre will break.
That horrifies me for several reasons:
- My photo model is pretty complex and has a ton of fields.
- My app is still in development and the photo model changes more than any other.
- I don't want to have my code breaking every time someone touches the photo model in the future if they forget to add the columns to the group statement on the tag searching argument.
So, can anyone help me understand how to rewrite this method so that it won't break PostgreSQL -- and ideally so that I won't have to include a list of all the fields that belong to this model in the solution, or at least not a manually maintained list?
So, it turns out I could solve this problem by replacing "group" with "select" in my tagged_with
method.
def self.tagged_with( string )
array = string.split(',').map{ |s| s.lstrip }
select('distinct photos.*').joins(:tags).where('tags.name' => array )
end
Problem solved! See this article for a great explanation as to why this is a better idea anyway. (Sorry, web site was removed later on and I don't recall what it said.) Also, thanks to Mark Westling for his answer on a spinoff question that solved my problem.
精彩评论