Ruby on Rails中的动态标签云

3
我已经从头开始使用这个教程在Ruby on Rails中实现了标签云。
当你在我的照片博客上点击一个标签,比如说Tokyo,所有被标记为Tokyo的照片都会被列出。我现在想要添加两个东西来使我的标签云更加动态,以便让你缩小列表:
  • 标签云应该被动态更新,这样它现在只显示与剩余照片相关联的标签,即Tokyo子集(字体大小相对于此子集进行缩放)。
  • 当你从这个子集标签云中点击一个标签,比如说2008,我希望列出所有被标记为Tokyo2008的照片(而不是所有被标记为2008的照片),最好是无限地。
我是Ruby的新手,无论我尝试了什么(太多了,这里不一一列举),似乎都无法实现其中任何一个。
以下是相关代码: photo.rb:
class Photo < ActiveRecord::Base
belongs_to :photo
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings
accepts_nested_attributes_for :tags

def self.tagged_with(name)
    Tag.find_by_name!(name).photos
end

def self.tag_counts
    Tag.select("tags.*, count(taggings.tag_id) as count").
    joins(:taggings).group("taggings.tag_id")
end

tag.rb:

class Tag < ActiveRecord::Base
    has_many :taggings
    has_many :photos, through: :taggings
end

tagging.rb:

class Tagging < ActiveRecord::Base
    belongs_to :tag
    belongs_to :photo
end

application_helper.rb:

module ApplicationHelper
def tag_cloud(tags, classes)
    max = 0
    tags.each do |t|
        if t.count.to_i > max
            max = t.count.to_i
        end
    end
    tags.each do |tag|
        index = tag.count.to_f / max * (classes.size - 1)
        yield(tag, classes[index.round])
    end
end
end

photos_controller.rb:

class PhotosController < ApplicationController

  def index
      if params[:tag]
      @photos = Photo.tagged_with(params[:tag])
      else
      @photos = Photo.order("created_at desc").limit(8)
      end
  end

  private
  def set_photo
      @photo = Photo.find(params[:id])
  end

  def photo_params
      params.require(:photo).permit(:name, :description, :picture, :tag_list, tags_attributes: :name)
  end
  end

index.html.erb:

<div id="tag_cloud">
  <% tag_cloud Photo.tag_counts, %w[xxs xs s m l xl xxl] do |tag, css_class| %>
  <%= link_to tag.name, tag_path(tag.name), class: css_class %>
  <% end %>
</div>

photos.css.scss:

#tag_cloud {
  width: 400px;
  line-height: 1.6em;
  .xxs { font-size: 0.8em; COLOR: #c3c4c4; }
  .xs { font-size: 1.0em; COLOR: #b9bdbd; }
  .s { font-size: 1.2em; COLOR: #b0b5b5; }
  .m { font-size: 1.4em; COLOR: #9da6a6; }
  .l { font-size: 1.6em; COLOR: #8a9797; }
  .xl { font-size: 1.8em; COLOR: #809090; }
  .xxl { font-size: 2.0em; COLOR: #778888; }
}

非常感谢您的帮助!

1个回答

1
如果我理解正确,您希望能够选择标记有一个或多个标签的照片。您需要更改您的函数:
def self.tagged_with(*names)
    joins(:tags).where(tags: { name: names })
end

参数名称:

def index
  if params[:tags]
    @photos = Photo.tagged_with(params[:tags])
  else
    @photos = Photo.order("created_at desc").limit(8)
  end
end

在视图中,当你定义方法current_tags时:
<div id="tag_cloud">
  <% tag_cloud Photo.tag_counts, %w[xxs xs s m l xl xxl] do |tag, css_class| %>
  <%= link_to tag.name, tag_path([tag.name, *current_tags].uniq), class: css_class %>
  <% end %>
</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接