在轨道中订购投票系统

时间:2014-07-04 11:47:00

标签: ruby-on-rails pins

我实现了一种简单的方法让用户赞成引脚,但我想通过upvotes的数量订购引脚,这是我的upvote系统:

app / controllers / pins_controller.rb

def upvote
  @pin = Pin.find(params[:id])
  @pin.votes.create
  redirect_to(pins_path)
end

应用/模型/ vote.rb

class Vote < ActiveRecord::Base

belongs_to :pin


end

应用/模型/ pin.rb

has_many :votes, dependent: :destroy

我的 routes.rb 看起来像是:

resources :pins do
  member do
    post 'upvote'
  end
en

所以我想要 app / views / pins / index.html.erb

显示最受欢迎的引脚以减少投票。

我知道acts_as_votable提供了一个系统来做到这一点,但由于我没有使用那个宝石来实现我的投票系统,我不确定使用它是个好主意。

您怎么看?

我的 app / views / pins / index.html.erb 如下:

<% @pins.each do |pin| %>
    <div class="box panel panel-default">
      <%= image_tag pin.image.url(:medium) %>
      <div class="panel-body">

        <p class="startupinfo">
          <%= pin.startupname %><span class="reward"><i class="fa fa-heart"></i> <%= pin.reward %></p></span>

        <p class="startupname"><%= pin.description %></p>

        <p class="startuptag"><i class="fa fa-map-marker turquoise"></i> <%= pin.tag %> <i class="fa fa-tags turquoise"></i> <%= pin.city %><%= link_to upvote_pin_path(pin), method: :post do %> <i class="fa fa-chevron-circle-up fa-1x" style="color:#28c3ab"></i>  <% end %>
            <%= pluralize(pin.votes.count, "upvote") %></p>

        <p class="users-edit">
        <%= link_to pin_path(pin), class: "btn btn-success" do %> Tweet <% end %>

        <% if pin.user == current_user %>
          <%= link_to 'Edit', edit_pin_path(pin) %>
          <%= link_to 'Delete', pin, method: :delete, data: { confirm: 'Are you sure?' } %></p>
        <% end %>
      </div>
    </div>
  <% end %>

基于BALOO ANSWER:

我跑了:

rails generate migration add_votescount_to_pins votes_count:integer

rails generate migration add_countercache_to_votes counter_cache:integer

我手动更新了迁移 _add_votescount_to_pins.rb ,所以它看起来像:

class AddVotescountToPins < ActiveRecord::Migration
  def change
    add_column :pins, :votes_count, :integer
    Pin.reset_column_information
        Pin.includes(:votes).all.each do |pin|
    Pin.update_counters(pin.id, :votes_count => pin.votes.size)
  end
end

我跑了:

rake db:migrate

然后我将以下行添加到 pins.controller.rb 中:

def index
    @pins = Pin.all
    @pins = Pin.order(votes_count: :desc)
  end

现在我的 schema.rb 文件如下所示:

# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20140704125839) do

  create_table "pins", force: true do |t|
    t.string   "description"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "user_id"
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
    t.string   "tag"
    t.string   "reward"
    t.string   "startupname"
    t.string   "city"
    t.string   "tweet"
    t.string   "logo"
    t.string   "website"
    t.string   "rewardcode"
    t.string   "logo_file_name"
    t.string   "logo_content_type"
    t.integer  "logo_file_size"
    t.datetime "logo_updated_at"
    t.integer  "votes_count"
  end

  add_index "pins", ["user_id"], name: "index_pins_on_user_id"

  create_table "startups", force: true do |t|
    t.string   "name"
    t.text     "description"
    t.text     "location"
    t.text     "tag"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "users", force: true do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "name"
    t.string   "provider"
    t.string   "uid"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

  create_table "votes", force: true do |t|
    t.integer  "pin_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "counter_cache"
  end

end

但是我的pin索引仍然没有以upvotes的数量排序! 有什么想法吗?

2 个答案:

答案 0 :(得分:1)

所以,当你投票时,它会摧毁?

您可以向引脚添加votes_count整数列,然后在投票中添加counter_cache

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

当有人为它投票时,这会增加某个引脚上的votes_count。

然后只需根据

进行查询
@pins = Pin.order(votes_count: :desc)

在您的迁移中,您需要根据现有投票更新votes_count。

add_column :pins, :votes_count, :integer, default: true
Pin.reset_column_information
Pin.all.each do |pin|
  Pin.reset_counters(pin.id, :votes)
end

答案 1 :(得分:0)

要在没有计数器缓存的情况下实现它,您可以尝试:

@pins = Pin.joins(:votes).select('pins.*, COUNT(votes.id) AS vote_count').group('votes.pins_id').order('vote_count DESC')