ruby on rails - How to only use tag_cloud for current_user? -


in application_controller have this:

  def tag_cloud     @tags = tag.top_20.sort{ |x,y| x.id <=> y.id } if current_user   end 

which make tag count work tags users, instead want tag_cloud show tags of current_user. tried this:

  def tag_cloud     @tags = current_user.tags.top_20.sort{ |x,y| x.id <=> y.id } if current_user   end 

but gave me error:

nomethoderror (undefined method `top_20' #<activerecord::associations::collectionproxy []>):   app/controllers/application_controller.rb:13:in `tag_cloud' 

even though top_20 defined in tag.rb:

class tag < activerecord::base   has_many :taggings      scope :top_20, -> {       where("taggings_count != 0").order("taggings_count desc").limit(15)     } end 

i'm using acts-as-taggable-on gem. thank you!

updates

user.rb

class user < activerecord::base   acts_as_tagger   acts_as_taggable   has_many :notifications   has_many :activities   has_many :activity_likes   has_many :liked_activities, through: :activity_likes, class_name: 'activity', source: :liked_activity   has_many :liked_comments, through: :comment_likes, class_name: 'comment', source: :liked_comment   has_many :valuation_likes   has_many :habit_likes   has_many :goal_likes   has_many :quantified_likes   has_many :comment_likes   has_many :authentications   has_many :habits, dependent: :destroy   has_many :levels   has_many :combine_tags   has_many :valuations, dependent: :destroy   has_many :comments   has_many :goals, dependent: :destroy   has_many :quantifieds, dependent: :destroy   has_many :results, through: :quantifieds   has_many :notes   accepts_nested_attributes_for :habits, :reject_if => :all_blank, :allow_destroy => true   accepts_nested_attributes_for :notes, :reject_if => :all_blank, :allow_destroy => true   accepts_nested_attributes_for :quantifieds, :reject_if => :all_blank, :allow_destroy => true   accepts_nested_attributes_for :results, :reject_if => :all_blank, :allow_destroy => true   has_many :active_relationships, class_name:  "relationship",                                   foreign_key: "follower_id",                                   dependent:   :destroy   has_many :passive_relationships, class_name:  "relationship",                                    foreign_key: "followed_id",                                    dependent:   :destroy   has_many :following, through: :active_relationships,  source: :followed   has_many :followers, through: :passive_relationships, source: :follower   attr_accessor :remember_token, :activation_token, :reset_token   before_save   :downcase_email   before_create :create_activation_digest   validates :name,  presence: true, length: { maximum: 50 }   valid_email_regex = /\a[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i   validates :email, presence: true, length: { maximum: 255 },                     format: { with: valid_email_regex },                     uniqueness: { case_sensitive: false }, unless: -> { from_omniauth? }   has_secure_password   validates :password, length: { minimum: 6 }   scope :publish, ->{ where(:conceal => false) }   user.tag_counts_on(:tags)    def count_mastered     @res = habits.reduce(0) |count, habit|     habit.current_level == 6 ? count + 1 : count     end   end    def count_challenged     @challenged_count = habits.count - @res   end      def self.from_omniauth(auth)       where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap |user|         user.provider = auth.provider         user.image = auth.info.image         user.uid = auth.uid         user.name = auth.info.name         user.oauth_token = auth.credentials.token         user.oauth_expires_at = time.at(auth.credentials.expires_at)         user.password = (0...8).map { (65 + rand(26)).chr }.join         user.email = (0...8).map { (65 + rand(26)).chr }.join+"@mailinator.com"         user.save!       end     end    def self.koala(auth)     access_token = auth['token']     facebook = koala::facebook::api.new(access_token)     facebook.get_object("me?fields=name,picture")   end     # returns hash digest of given string.   def user.digest(string)     cost = activemodel::securepassword.min_cost ? bcrypt::engine::min_cost :                                                   bcrypt::engine.cost     bcrypt::password.create(string, cost: cost)   end    # returns random token.   def user.new_token     securerandom.urlsafe_base64   end    # remembers user in database use in persistent sessions.   def remember     self.remember_token = user.new_token     update_attribute(:remember_digest, user.digest(remember_token))   end    # forgets user. not sure if remove   def forget     update_attribute(:remember_digest, nil)   end    # returns true if given token matches digest.   def authenticated?(attribute, token)     digest = send("#{attribute}_digest")     return false if digest.nil?     bcrypt::password.new(digest).is_password?(token)   end    # activates account.   def activate     update_attribute(:activated,    true)     update_attribute(:activated_at, time.zone.now)   end    # sends activation email.   def send_activation_email     usermailer.account_activation(self).deliver_now   end    def create_reset_digest     self.reset_token = user.new_token     update_attribute(:reset_digest,  user.digest(reset_token))     update_attribute(:reset_sent_at, time.zone.now)   end    # sends password reset email.   def send_password_reset_email     usermailer.password_reset(self).deliver_now   end     # returns true if password reset has expired.   def password_reset_expired?     reset_sent_at < 2.hours.ago   end    def good_results_count     results.good_count   end    # follows user.   def follow(other_user)     active_relationships.create(followed_id: other_user.id)   end    # unfollows user.   def unfollow(other_user)     active_relationships.find_by(followed_id: other_user.id).destroy   end    # returns true if current user following other user.   def following?(other_user)     following.include?(other_user)   end  private       def from_omniauth?        provider && uid      end        # converts email lower-case.     def downcase_email        self.email = email.downcase unless from_omniauth?      end      # creates , assigns activation token , digest.     def create_activation_digest       self.activation_token  = user.new_token       self.activation_digest = user.digest(activation_token)     end end 

tags_controller

class tagscontroller < applicationcontroller   def index     @tags = tag.all   end    def show     @tag = tag.find(params[:id])   end end 

routes.rb

get 'tags/:tag', to: 'pages#home', as: :tag 

schema.rb

  create_table "taggings", force: true |t|     t.integer  "tag_id"     t.integer  "taggable_id"     t.string   "taggable_type"     t.integer  "tagger_id"     t.string   "tagger_type"     t.string   "context",       limit: 128     t.datetime "created_at"   end    add_index "taggings", ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true   add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"    create_table "tags", force: true |t|     t.string  "name"     t.integer "taggings_count", default: 0   end    add_index "tags", ["name"], name: "index_tags_on_name", unique: true    create_table "users", force: true |t|     t.string   "name"     t.boolean  "conceal",           default: false     t.string   "email"     t.text     "missed_days"     t.text     "missed_levels"     t.string   "provider"     t.string   "uid"     t.string   "oauth_token"     t.datetime "oauth_expires_at"     t.datetime "created_at",                        null: false     t.datetime "updated_at",                        null: false     t.string   "password_digest"     t.string   "remember_digest"     t.boolean  "admin",             default: false     t.string   "activation_digest"     t.boolean  "activated",         default: false     t.datetime "activated_at"     t.string   "reset_digest"     t.datetime "reset_sent_at"     t.string   "image"   end 

goal.rb

class goal < activerecord::base     scope :publish, ->{ where(:conceal => false) }     belongs_to :user     has_many :comments     has_many :notifications     has_many :notes     acts_as_taggable     scope :accomplished, -> { where(accomplished: true) }     scope :unaccomplished, -> { where(accomplished: false) }     scope :private_submit, -> { where(private_submit: true) }     scope :public_submit, -> { where(private_submit: false) }     validates :name, presence: true     has_many :goal_likes   has_many :likers, through: :goal_likes, class_name: 'user', source: :liker      scope :top_3, ->       order("deadline").       limit(3)     end end 

your issue acts-as-taggable-on not use tag class. or more specific - works when tags.top_20 since calling on tag class. user#tags relationship uses actsastaggableon::tag explains nomethoderror.

actsastaggableon seems have functionality built in though:

current_user.tags.most_used(20) 

addition:

i combining tags several model instances single tag cloud, showing in sidebar.

there nothing in requirement says need create tag or tagging class. in fact doing cause , other developers bunch of grief. fact tag cloud on home page works not change fact creating bunch of future issues replacing 2 relatively complex components (tagging , tag classes) tiny stubs willy-nilly.

if @ tag_cloud implementation pretty easy see takes activerecord::relation or collection or old enumerable such array.

module actsastaggableon   module tagshelper     # see wiki example using tag_cloud.     def tag_cloud(tags, classes)       return [] if tags.empty?        max_count = tags.sort_by(&:taggings_count).last.taggings_count.to_f        tags.each |tag|         index = ((tag.taggings_count / max_count) * (classes.size - 1))         yield tag, classes[index.nan? ? 0 : index.round]       end     end   end end 

since collections fancy pants versions of arrays merging them easy as:

@tags = foo.tags + bar.tags 

however joining relations bit more complex since rails not support sql or clause. (its coming in rails 5). either have load , merge collections above or create own clause arel if multiple sql queries performance issue.


Comments

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -