私のアプリでは、users
が(Redditのようなやり方で)投票できるようになるでしょう。これには、jokes
、recipes
、rules
などのupvote/downvote構造が含まれます。今、joke
モデルを例に使用して多形votes
を設定しようとしています。Rails Polymorphic投票構造
私は私のschema
に見られるように、多型変数としてvotes
を追加しました:
create_table "votes", force: :cascade do |t|
t.integer "value"
t.integer "user_id"
t.integer "voteable_id"
t.string "voteable_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "votes", ["user_id"], name: "index_votes_on_user_id"
add_index "votes", ["voteable_type", "voteable_id"], name: "index_votes_on_voteable_type_and_voteable_id"
そして私はrank
のための私のjokes
テーブルにfloat
列を追加しました。
私はvote
モデル作成:私はvotes_controller
を持って
class User < ActiveRecord::Base
...
has_many :jokes, dependent: :destroy
has_many :votes, dependent: :destroy
end
:
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :voteable, polymorphic: true
after_save :update_vote
private
def update_joke
vote.update_rank
end
end
をそして、私のjoke
モデルに適切な更新をした:
class Joke < ActiveRecord::Base
belongs_to :user
has_many :votes, as: :voteable, dependent: :destroy
default_scope { order('rank DESC')}
def up_votes
votes.where(value: 1).count
end
def down_votes
votes.where(value: -1).count
end
def points
votes.sum(:value)
end
def update_rank
new_rank = points
update_attribute(:rank, new_rank)
end
end
そして、私のuser
モデル次のようになります。
class VotesController < ApplicationController
def up_vote
update_vote(1)
redirect_to :back
end
def down_vote
update_vote(-1)
redirect_to :back
end
private
def update_vote(new_value)
@joke = Joke.find(params[:joke_id])
@vote = @joke.votes.where(user_id: current_user.id).first
if @vote
@vote.update_attribute(:value, new_value)
else
@vote = current_user.votes.create(value: new_value, joke: @joke)
end
end
end
そして最後に、この_voter.html.erb
部分:
resources :jokes do
patch :approve, on: :member
patch :reject, on: :member
post '/up-vote' => 'votes#up_vote', as: :up_vote
post '/down-vote' => 'votes#down_vote', as: :down_vote
end
:私も私の
routes
に以下の調整を行いました
<% @jokes.each do |joke| %>
<div class="row">
<% if joke.approved == true && joke.kids == true %>
<%= render partial: 'votes/voter', locals: { joke: joke } %>
<div class="col-xs-11"> <!-- non vote container -->
<h2 id="joke-title" style="margin-top: 0px">
<%= joke.title %>
<% if joke.kids == true %>
<%= image_tag 'icon_kids.jpg', style: "height: 25px; margin-left: 10px" %>
<% end %>
<% if joke.mixed == true %>
<%= image_tag 'icon_mixed.jpg', style: "height: 25px; margin-left: 10px" %>
<% end %>
</h2>
<p id="joke-body"><%= joke.body %></p>
<p><strong>Submitted by: <%= joke.user.first_name %></strong></p>
<% if current_user && (current_user == joke.user || current_user.admin) %>
<%= link_to edit_joke_path(joke) do %>
<span style="color: blue" class="glyphicon glyphicon-pencil" aria-hidden="true"></span><span style="color: blue">Edit Joke</span>
<% end %>
<%= link_to joke_path(joke), data: {:confirm => 'Are you sure?'}, :method => :delete do %>
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>Delete Joke
<% end %>
<% end %>
</div> <!-- non vote container -->
</div> <!-- joke row -->
<% end %>
<div class="row text-center">
<hr style="width: 50%; margin-top: 30px; margin-bottom: 30px">
</div> <!-- row -->
<% end %>
:
<div class="text-center col-xs-1">
<% if current_user %>
<div class="width: 100%"><%= link_to " ", joke_up_vote_path(joke), class: 'glyphicon glyphicon-chevron-up', method: :post, style: "margin-right: 0; margin-left: 0" %></div>
<% else %>
<div class="width: 100%"><%= link_to " ", new_user_session_path, class: 'glyphicon glyphicon-chevron-up', method: :post, style: "margin-right: 0; margin-left: 0" %></div>
<% end %>
<div class="width: 100%"><h3 style="margin-top: 0; margin-bottom: 0"><strong><%= joke.points %></strong></h3></div>
<% if current_user %>
<div class="width: 100%"><%= link_to " ", joke_up_vote_path(joke), class: 'glyphicon glyphicon-chevron-down', method: :post, style: "margin-right: 0; margin-left: 0" %></div>
<% else %>
<div class="width: 100%"><%= link_to " ", new_user_session_path, class: 'glyphicon glyphicon-chevron-down', method: :post, style: "margin-right: 0; margin-left: 0" %></div>
<% end %>
</div>
は私の
otherjokes/kids.html.erb
ページに表示されます
今、私が冗談に投票しようとすると、votes_controller
の末尾に@vote = current_user.votes.create(value: new_value, joke: @joke)
という行が呼び出され、unknown attribute 'joke' for Vote.
が呼び出されます。
私はこのシステムを投票が必要な他の将来のモデルにも適用できるようにしたいと思っています。また、(可能であれば)「Rubyのやり方」にすることもできます。誰も私がこれを適切に構造化するのを助けることができる?
これは 'jokes_controller'か' votes_controller'にありますか?私がジョークコントローラのインデックスアクトンに入れた場合、私はその行に '#JokesController:0x007fb99f5adf88>のための'未定義のローカル変数またはメソッド 'new_value'というエラーを受け取ります。 – Liz
あなたのvotes_controllerのほぼ同じ行を置き換えるものです。それはエラーを打ち消した行です。 – AmShaegar
これは#のエラーを '未定義メソッド 'update_vote'に変更しました。 –
Liz