修改控制器以使用 Heroku 的 Postgres DB

Modify Controller To Work With Heroku's Postgres DB

我的专辑评论应用程序有一个名为 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')

这在很大程度上正确构建了 table,但我无法附上专辑封面。当我尝试将 :image 添加到上面的 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 %>

我在我的开发机器和 Heroku 上使用 Postgres。在许多情况下,我发现 .group 很痛苦,可能是因为我不明白它在幕后到底在做什么。我使用 group_byedit 我能够在分组依据之前添加顺序。我自己的订购问题来自一些加入问题。

您可以使用:

def artists
  @pin_albums = Pin.all.order(:artist).group_by(&:album) 
end

我用这个方法成功了。它将 return 一个哈希格式为:

@pin_albums = {"album1" => [#<pin1...>, #<pin2...], "album2" => [#<pin3..>...}

看你的输出,也许应该是

@pin_albums = Pin.all.order(:artist).group_by(&:artist)

这样你的哈希就是

{"artist1" => [#<pin1.... ], "artist2" => [....]} 

然后很容易将该数据处理成您显示的 table 格式。

您可以像使用当前视图代码一样做类似的事情,为简洁起见,我省略了 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。