我的专辑评论应用程序有一个名为Pins的评论模型,其中包含艺术家,专辑(标题)和图像属性。 (图像是专辑封面艺术,这是一个回形针附件)
我正在生成一个已经在网站上评论过的每位艺术家的列表,以及该艺术家的每张专辑。这是我的代码,在我的本地数据库上工作正常:
Pin.rb型号:
class Pin < ActiveRecord::Base
attr_accessible :description, :image, :image_remote_url, :artist, :album, :date, :rank, :video, :video_html, :rating, :year, :title, :tag_list
has_attached_file :image, styles: { :medium => "320x240>", :small => "200x200>" }
validates :description, presence: true
validates :user_id, presence: true
validates :artist, presence: true
validates :album, presence: true
validates :year, presence: true
validates :rating, presence: true
validates_attachment :image, presence: true,
content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/gif', 'image/png'] },
size: { less_than: 5.megabytes }
has_many :videos
end
针脚架构:
create_table "pins", force: true do |t|
t.text "description", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "image_remote_url"
t.string "artist"
t.string "album"
t.integer "date"
t.integer "rank"
t.string "video_html"
t.string "video"
t.string "rating"
t.string "year"
t.string "title"
end
引脚控制器:
def artists
@pin_albums = Pin.group(:album).order('artist')
end
艺术家页面浏览:
<div class="artist_list">
<% last_artist ||= nil %>
<table id="artist">
<tr>
<th>Artist</th>
<th></th>
<th>Album</th>
</tr>
<% @pin_artists.each do |pin| %>
<tr>
<td><%= (last_artist == pin.artist) ? '' : pin.artist %></td>
<td><%= image_tag(pin.image) %></td>
<td><%= link_to pin.album, copy_pin_path(pin) %></td>
</tr>
<% last_artist = pin.artist %>
<% end %>
</table>
</div>
这给了我一个看起来像这样的输出:
推送到Heroku后,我收到以下错误:
ActionView::Template::Error (PG::GroupingError: ERROR: column "pins.id" must appear in the GROUP BY clause or be used in an aggregate function
在谷歌搜索后,我发现.group方法不适用于Postgres DB,所以我需要使用Select方法。我想出了这个:
引脚控制器:
@pin_artists = Pin.select(:album, :artist).distinct.order('artist')
这大部分都正确地构建了表格,但是我无法附加专辑封面。当我尝试添加:image to teh select方法时,我得到:
SQLite3::SQLException: no such column: image: SELECT DISTINCT "pins"."album", "pins"."artist", image FROM "pins" ORDER BY artist
如何正确编码我的控制器,以便在视图中调用pin.image?
编辑:
我接下来接受的答案是我正在寻找的,但我仍然需要在我看来改变一些事情。这是最终版本,仅显示艺术家一次,每个专辑只显示一次。
控制器:
@pin_albums = Pin.all.order(:artist).group_by(&:artist)
查看:
<table id="artist">
<% last_artist ||= nil %>
<% last_album ||= nil %>
<% @pin_albums.each do |artist, pins| %>
<tr>
<td colspan="2" class="artist-name"><%= (last_artist == artist) ? '' : artist %></td>
</tr>
<% pins.each do |pin| %>
<% if last_album != pin.album %>
<tr>
<td><%= link_to image_tag(pin.image), pin %></td>
<td><%= link_to pin.album, copy_pin_path(pin) %></td>
</tr>
<% last_album = pin.album %>
<% end %>
<% end %>
<% last_artist = artist %>
<% end %>
答案 0 :(得分:0)
我在我的开发机器和Heroku上使用Postgres。在许多情况下,我发现.group
很痛苦,可能是因为我没有得到它真正在幕后做的事情。我使用group_by
,编辑我可以在分组前添加订单。我自己的订购问题来自一些加入问题。
您可以使用:
def artists
@pin_albums = Pin.all.order(:artist).group_by(&:album)
end
我已成功使用此方法。它将以以下格式返回哈希:
@pin_albums = {"album1" => [#<pin1...>, #<pin2...], "album2" => [#<pin3..>...}
看看你的输出,也许它应该是
@pin_albums = Pin.all.order(:artist).group_by(&:artist)
这样你的哈希是
{"artist1" => [#<pin1.... ], "artist2" => [....]}
然后,将这些数据操作为您已经显示的表格格式会很容易。
你可以像使用当前的视图代码一样做这样的事情,为了简洁,我省略了html和.erb:
last_artist ||= nil
@pin_albums.each do |artist,pins|
pins.each do |pin|
(last_artist == artist) ? '' : artist
image_tag(pin.image)
link_to pin.album, copy_pin_path(pin)
end
last_artist = artist
end
请注意,您只是使用嵌套循环,每个艺术家的针脚都会循环播放。它还为您提供了一个很好的哈希作为数据结构,如果将来需要,可以很容易地转换为json。