代码之家  ›  专栏  ›  技术社区  ›  sf2k

Rails:如何增加counter_cache?

  •  1
  • sf2k  · 技术社区  · 9 年前

    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    :::已解决:::

    能够在投票模型上计算counter_cache并在Topics中使用。更新了以下问题。一旦Topic模型有了votes_count,我所要做的就是将其放在视图中,并在控制器中更新计数。结果很简单。然而,寻找信息并不是,所以这应该会帮助其他人摆脱困境,尽管它有着令人困惑的荣耀。一直往下找答案。

    干杯

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    :::编辑:::

    :::历史记录见下文:::

    这是对原始帖子的编辑。在我尝试宝石解决方案之前,我真的很接近我所拥有的。我使用了 注释缓存 投票模型 但现在我不知道如何增加缓存。

    class Vote < ActiveRecord::Base
        belongs_to :topic, :counter_cache => true
    end
    

    并且在视图中称为topic.votes.size,现在它显示的计数没有活动记录枚举。

    <td><%= pluralize(topic.votes.size, "vote") %></td>
            <td><%= button_to '+1', upvote_topic_path(topic), method: :post %></td>
            <td><%= button_to '-1', downvote_topic_path(topic), method: :post %></td>
    

    索引html.erb

    Listing Topics
    
    Title   
    test    1 vote  [+1] [-1]   Delete
    
    New Topic
    

    但comment_cache不允许负数。我仍然在记录上使用创建/销毁,而不是在计数中加减一个数字。如何递增和递减?这些方法表示我缺少值。目前,@topic.votes.last.destroy失败是有道理的,因为没有更多的选票可以销毁,因此总数不能低于零。

    如何设置以使comment_cache值递增/递减,从而使负数成为可能?我尝试了@topic.votes.increment和@topic.wotes.incredent_counter,但他们要求两个参数,我不知道要用什么。尝试

    @topic.increment_counter(:votes_count, params[:id])

    但没有运气。

    NoMethodError in TopicsController#upvote
    undefined method `increment_counter' for #<Topic:0x007f87d974a4b0>
    
    Extracted source (around line #433):
    431
    432
    433
    434
    435
    436
    
          else
            match = match_attribute_method?(method.to_s)
            match ? attribute_missing(match, *args, &block) : super
          end
        end
    

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    :::这行下面的历史记录:::

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    再次回顾Rails,我试图对主题进行简单的投票计数。我要做的是增加/减少投票记录中的计数(整数)列。

    主题has_may:投票,投票属于:主题

    主题_控制器.rb 我用过

    def upvote
        @topic = Topic.find(params[:id])
        @topic.votes.increment_counter(:tally, params[:id])
        redirect_to(topics_path)
      end
    
      def downvote
        @topic = Topic.find(params[:id])
        @topic.votes.decrement_counter(:tally, params[:id])
        redirect_to(topics_path)
      end
    

    但我得到了一个有趣的ActiveRecord键,而不是视图中的值,而不是投票数。

    index.html.erb:

    from the view
    <td><%= pluralize(topic.votes(:tally), "vote") %></td>
    <td><%= button_to '+1', upvote_topic_path(topic), method: :post %></td>
    <td><%= button_to '-1', downvote_topic_path(topic), method: :post %></td>
    
    result of view
        test    #<Vote::ActiveRecord_Associations_CollectionProxy:0x007fbb16451f68> votes   
    
            Delete
    

    从…起 Rails控制台 尽管增量没有显示:

      2.1.5 :022 > Vote.first
      Vote Load (0.5ms)  SELECT  "votes".* FROM "votes"  ORDER BY "votes"."id" ASC LIMIT 1
     => nil 
    
    2.1.5 :023 > Vote
     => Vote(id: integer, topic_id: integer, created_at: datetime, updated_at: datetime, tally: integer) 
    

    我想我已经设置了 路由.rb 好的,但我不确定是双人间

    Rails.application.routes.draw do
      resources :topics do
        member do
          post 'upvote'
          post 'downvote'
        end
      end
    
      root 'topics#index'  
    end
    

    无论如何,我认为这要么是错误的递增方法,要么是我缺少的东西。感谢任何帮助。干杯

    2 回复  |  直到 7 年前
        1
  •  1
  •   abbott567    9 年前

    你有一个用户模型来处理投票吗?如果是这样的话,有一个非常棒的宝石可以处理这个问题,叫做 acts_as_votable - https://github.com/ryanto/acts_as_votable

    您只需捆绑gem,运行迁移,然后添加 可旋转动作 主题模型,以及 acts_as_voter 对于您的用户模型,您可以使用一系列帮助器方法。

    主题控制器.rb

        def upvote
            @topic.upvote_by current_user
            redirect_to :back
        end
    
        def downvote
            @topic.downvote_by current_user
            redirect_to :back
        end
    

    路线.rb

        resources :topics do
          member do
            get "upvote", to: "topics#upvote"
            get "downvote", to: "topics#downvote"
          end
        end
    

    /主题/show.html.erb

        <%= link_to upvote_topic_path(@topic), method: :get  do %>
        <%= link_to downvote_topic_path(@topic), method: :get  do %>
    
        <%= pluralize(@topic.get_upvotes.size, 'Vote') %>
    
        2
  •  1
  •   sf2k    9 年前

    ::已解决::

    我能够在投票模型中使用counter_cache解决这个问题。现在可以用正值和负值进行投票。好极了

    在主题中添加了新列。

    class AddVotesCount < ActiveRecord::Migration
      def change
        add_column :topics, :votes_count, :integer, :default => 0
    
      end
    end
    

    更新投票模型

    class Vote < ActiveRecord::Base
            belongs_to :topic, :counter_cache :true
    end
    

    现在,在主题控制器中,我可以使用

    @topic.votes_count += 1
    .
    .
    .
    @topic.votes_count -= 1
    

    我可以使用@topic.update_attributes,但由于某种原因,我发现它不可靠,所以我在每个方法中都选择了@topic.save。

    该视图现在只使用topics.votes_count,效果很好。

    <td><%= pluralize(topic.votes_count, "vote") %></td>
            <td><%= button_to '+1', upvote_topic_path(topic), method: :post %></td>
            <td><%= button_to '-1', downvote_topic_path(topic), method: :post %></td>
    

    这在不需要用户模型和/或acts_as_votable gem的情况下工作。虽然我将来很可能会使用宝石,但如果没有它,我想办法让它发挥作用还是很不错的。

    干杯