0

ユーザーがピンに賛成票を投じられるようにする簡単な方法を実装しましたが、賛成票の数でピンを並べ替えたいと思います。これが私の賛成票システムです。

app/controllers/pins_controller.rb

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

アプリ/モデル/投票.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が欲しい

賛成票の多いピンから賛成票の少ないピンまでを表示します。

act_as_votableがそれを行うためのシステムを提供していることは知っていますが、投票システムを実装するためにその gem を使用しなかったので、それを使用するのが良い考えかどうかはわかりません。

どう思いますか?

私の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 の回答に基づく:

私は走った:

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

しかし、私のピン インデックスはまだ賛成票の数で並べ替えられません。何か案は?

4

2 に答える 2

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
于 2014-07-04T12:08:44.883 に答える
0

カウンターキャッシュなしでそれを達成するには、これを試すことができます:

@pins = Pin.joins(:votes).select('pins.*, COUNT(votes.id) AS vote_count').group('votes.pins_id').order('vote_count DESC')
于 2014-07-04T12:21:17.983 に答える