You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Ruby on Rails中为Bootstrap Nav-pills分配active类的实现方案

嘿,这个需求在Rails博客开发里太常见了!针对你的分类结构(主分类+子分类),我给你分享几个实用的实现方式,先回答你最关心的问题:用ERB结合if语句完全可以实现,但把逻辑抽成Helper会更符合Rails的最佳实践,让代码更干净易维护。

实现方法

方法一:直接在ERB视图中写条件判断

如果你的导航结构比较简单,直接在视图里写if判断是最直接的方式。首先要确保在对应的控制器动作中拿到当前分类对象:

第一步:在控制器中赋值当前分类

  • 分类详情页(BlogCategoriesController#show):
def show
  @category = BlogCategory.find(params[:id])
end
  • 文章详情页(ArticlesController#show):
def show
  @article = Article.find(params[:id])
  @category = @article.category # 关联到文章所属的分类
end

第二步:在视图中判断并添加active类

假设你的导航是遍历主分类并展开子分类,代码可以这么写:

<% # 遍历所有主分类(parent_id为nil的分类) %>
<% BlogCategory.where(parent_id: nil).each do |main_category| %>
  <li class="<%= 'active' if @category&.id == main_category.id || @category&.parent_id == main_category.id %>">
    <%= link_to main_category.name, blog_category_path(main_category) %>
    
    <% # 遍历当前主分类下的子分类 %>
    <ul class="sub-categories">
      <% main_category.children.each do |sub_category| %>
        <li class="<%= 'active' if @category&.id == sub_category.id %>">
          <%= link_to sub_category.name, blog_category_path(sub_category) %>
        </li>
      <% end %>
    </ul>
  </li>
<% end %>

这里用了&.安全导航操作符,避免@category为nil时(比如在非博客页面)出现报错。主分类的active判断逻辑是:当前分类是主分类本身,或者当前分类是它的子分类;子分类则只需要ID匹配即可。

方法二:将逻辑抽成Helper方法(推荐)

如果导航需要在多个页面复用,或者逻辑更复杂,把判断逻辑放到Helper里会让视图代码更简洁,也方便后续维护:

第一步:创建Blog Helper

在app/helpers/blog_helper.rb中添加方法:

module BlogHelper
  def category_active_class(category, current_category)
    # 如果没有当前分类,返回空字符串
    return '' unless current_category

    if category.parent_id.nil?
      # 主分类:当前分类是自己或子分类时添加active
      'active' if current_category.id == category.id || current_category.parent_id == category.id
    else
      # 子分类:仅ID匹配时添加active
      'active' if current_category.id == category.id
    end
  end
end

第二步:在视图中调用Helper

现在视图代码会清爽很多:

<% BlogCategory.where(parent_id: nil).each do |main_category| %>
  <li class="<%= category_active_class(main_category, @category) %>">
    <%= link_to main_category.name, blog_category_path(main_category) %>
    
    <ul class="sub-categories">
      <% main_category.children.each do |sub_category| %>
        <li class="<%= category_active_class(sub_category, @category) %>">
          <%= link_to sub_category.name, blog_category_path(sub_category) %>
        </li>
      <% end %>
    </ul>
  </li>
<% end %>

额外注意事项

  • 路由设置:确保你已经配置了正确的路由,比如resources :blog_categories, only: [:show],这样blog_category_path才能正常工作。
  • 处理非博客页面:当用户访问首页或其他非博客分类/文章页时,@category会是nil,这时候Helper会返回空字符串,不会给任何分类添加active类,符合预期。
  • 子分类关联:确保你的BlogCategory模型中已经定义了父子关联:
class BlogCategory < ApplicationRecord
  has_many :children, class_name: "BlogCategory", foreign_key: "parent_id"
  belongs_to :parent, class_name: "BlogCategory", optional: true
end

这样就能完美实现“根据当前页面的文章/分类,给对应主分类和子分类添加active类”的需求啦!

内容的提问来源于stack exchange,提问作者Jake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:16:59