【问题标题】:Rails category navigation with tags带有标签的 Rails 类别导航
【发布时间】:2010-12-19 15:56:41
【问题描述】:

我想为我的 Web 应用程序创建一个导航系统,其中有几个主要类别的文章和几个子标签。

例如,在“写作”类别中,可能有“散文”、“诗歌”和“小说”等子类别。

每篇文章都有一个标签列表。如果有人点击小说类别显示页面上的标签“意大利”,我不希望其他类别(如散文或诗歌)中具有相同标签“意大利”的文章出现在该页面上。

当点击标签时,显示页面将是一个类别显示页面,其中包含该类别中具有该特定标签的所有文章的标签过滤器。它不会是一个标签显示页面。

另外,我想要一个带有相关标签的侧边栏。这些标签将与分类显示页面上按降序显示的相同文章中的标签。我在标签页面本身上获得了相关标签,但不受类别约束。

到目前为止,我可以让类别页面和标签页面分开工作,但我想将两者结合起来。

我目前使用 Acts as Taggable on Steroids 作为标签和 Acts as Tree 作为类别。

有什么想法吗?

【问题讨论】:

  • 我不确定,但您可以尝试创建一个 Tag 模型并将其设置为 belongs_to :category。您需要将 category_id 添加到您的标签表中。然后你可以做 some_category.tags 和 Article.find_tagged_with(some_category.tags) (或类似的——我不确定如何使用 AaToS)。您还可以查看 mbleigh 的 ActsAsTaggableOn fork:github.com/mbleigh/acts-as-taggable-on 它具有一些内置的相关标签功能。

标签: ruby-on-rails navigation tags categories


【解决方案1】:

我认为您在这里混合了两个概念,至少在问题中,也许不是在您的应用程序中。您有一个使用acts_as_tree 建模的类别列表。这支持子类别。标签不应属于子类别。您想或多或少地按标签和类别进行过滤。您应该能够编写返回文章列表的简单查询,例如:

@articles = Article.find(:all, 
        :include => "categories"
        :conditions => ["(category_id = ? OR categories.parent_id = ?) AND tag_id = ?",
                         category_id, category_id, tag_id])

我用来执行此操作的一种更复杂的方法是使用 Solr 进行分面导航。它支持将这些过滤器与全文搜索相结合。

【讨论】:

    【解决方案2】:

    马特,非常感谢!这似乎比我最初想的要简单得多。

    但是,我的目标是在导航中包含子类别。这个想法是父类别将包含子类别中的所有内容,并且如果您单击子类别,它将缩小范围。我想我会检查一下 Solr 的想法,看看它是否让我的代码更简单。

    经过一番反复试验后,我的代码开始工作了。虽然看起来很乱。有什么简化的建议吗?

    顺便说一句,其中一些方法是通过 AATOS 定义的

    在类别视图中#show:

    <% for article in @articles %>
    
      <%= link_to article.name, article %>
      <% unless article.tag_list.empty? %>
      <p class="tags">
       Tags:
       <%= render :partial  => article.tags %>
       </p>
      <% end %>
    

    对于标签/导航侧边栏,我有:

    <% tag_cloud @tags, %w(css1 css2 css3 css4) do |tag, css_class| %>
    <%= link_to tag, category_path(:filter => tag.name), :class => css_class %>
    <% end %>
    

    类别模型,(不理想但有效)

    class Category < ActiveRecord::Base
    acts_as_tree
    has_many :articles
    has_many :child_articles, :through => :children, :source => :articles
    
    def grand_articles
    children.map {|c| c.child_articles}.flatten.uniq
    end
    
    def to_param
    name
    end
    
    def family
    child_articles + articles + grand_articles
    end
    

    结束

    最后是丑陋的控制器代码:

    class CategoriesController < ApplicationController
    
     def show
     @category = Category.find_by_name(params[:id])
     if (params[:filter]).nil?
     @articles = @category.family
     else
     @articles = Article.find_tagged_with(params[:filter],
     :conditions => ["articles.id IN (?)", @category.family])
     end
     @tags = 
     if (params[:filter]).nil?
     Article.tag_counts :conditions => ["articles.id IN (?)", @category.family]
     else
     Article.find_related_tags(params[:filter],
     :conditions => ["tags.id IN (?)",  @category.family.map {|a| a.tags}.flatten.uniq])
     end
    

    它可以工作,但它又是丑陋而脆弱的代码。我敢肯定我在这里犯了一些可怕的罪。对清理它的任何建议表示赞赏。

    【讨论】:

      猜你喜欢
      • 2020-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多