Listing all tags for an acts_as_taggable

2019-08-05 11:50发布

I have an app that has factoids that have tags using the acts_as_taggable gem. I currently have it setup so that when on the index page for the factoids, clicking on any of the tags filters the factoids by that tag. What I am attempting to do now is create an index page that lists all of the tags in the app. This seemed rather straight forward...

  1. create a tag.rb
  2. create a tags_controller.rb
  3. add a view in tags/index.html.erb

The problem is that this causes my previously implemented search to break. If there are any additional things that are needed, please let me know.

FactoidsController (the index part of it)

class FactoidsController < ApplicationController
  helper_method :sort_column, :sort_direction
  before_filter :authenticate_user!

  # GET /factoids
  # GET /factoids.json
  def index
    if params[:tag]
      @factoids = Factoid.tagged_with(params[:tag]).order(sort_column + ' ' + sort_direction).paginate(:per_page => 15, :page => params[:page])
    else
      @factoids = Factoid.search(params[:search]).order(sort_column + ' ' + sort_direction).paginate(:per_page => 15, :page => params[:page])
    end

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @factoids }
    end
  end

  def tagged
    if params[:tag].present?
      @factoids = Factoid.tagged_with(params[:tag])
    else
      @factoids = Factoid.postall
    end
  end

  private
  def sort_column
    params[:sort] || "created_at"
  end

  def sort_direction
    params[:direction] || "desc"
  end

end

Tags Controller

class TagsController < ApplicationController
  helper_method :sort_column, :sort_direction
  before_filter :authenticate_user!

  # GET /factoids
  # GET /factoids.json
  def index
    @tags = Tag.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @tags }
    end
  end

  private
  def sort_column
    params[:sort] || "created_at"
  end

  def sort_direction
    params[:direction] || "desc"
  end

end

Routes

QaApp::Application.routes.draw do
  devise_for :users

  resources :factoids

  resources :tags

  get "home/index"

  match 'tagged' => 'factoids#tagged', :as => 'tagged'

  get 'tags/:tag', to: 'factoids#index', as: :tag

  root :to => 'home#index'

end

1条回答
该账号已被封号
2楼-- · 2019-08-05 12:10

You dont need to go through all the trouble of creating a tag model and controller. `acts-as-taggable-on provides a method to find a list of all tags for the model.

2.0.0-p451 :008 > Factoid.tag_counts
  ActsAsTaggableOn::Tag Load (2.0ms)  SELECT tags.*, taggings.tags_count AS count FROM "tags" JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count FROM "taggings" INNER JOIN factoids ON factoids.id = taggings.taggable_id WHERE (taggings.taggable_type = 'Factoid' AND taggings.context = 'tags') AND (taggings.taggable_id IN(SELECT factoids.id FROM "factoids")) GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0) AS taggings ON taggings.tag_id = tags.id
 => #<ActiveRecord::Relation [#<ActsAsTaggableOn::Tag id: 1, name: "tag">]>

This will return a ActiveRecord::Relation of all the tag objects. You can run map on it to get a array of tags

Factoid.tag_counts.map(&:name)
 => ["tag"]
查看更多
登录 后发表回答