biovision-vote 0.1.2.170925 → 0.2.180610

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2896e74fd3e5c25c96555df47134054a1dd6f590
4
- data.tar.gz: 9864256f76fcc4c69b4a8e3a051f92ec7a1278f0
2
+ SHA256:
3
+ metadata.gz: adda0f4c749b69d036ee7ed68eeb0bf5c7b239b0bcf1e319a0b41047159fa528
4
+ data.tar.gz: 70afc612c239040da36ab2d3c4e576749bd2ae5301373ece07dd80029f97a118
5
5
  SHA512:
6
- metadata.gz: 2e04835cfee1d598a18143385563b64aaa394368bf5cf419cff484e45265579d8a1823ce1f5413827cb7b7bb76801e8ab612d20fd8083dd6cfd1ea60f9f3ad97
7
- data.tar.gz: d34535db6f6717c29c73268052f0f578713bc1da3ec0c26a9af184f0a72345daab2054b57727d970f8aa8d116bc78d8775ab53e818c1c07efdca5a1bca61f60a
6
+ metadata.gz: bc1b959e92bb5d0bfb80d52fc8253bb3b5c049348cdb38bb2aa55a8aa5622a7b112dc464169dc273a0e3880a6eb93ecaf3255ba5d2bc87d1c53cfb02c42dcd94
7
+ data.tar.gz: 9d72d310271a1939606abfbe25e8ae66ad06932caf9293002a4a08a3ad43da0438cf0ad937c546db393076211cedc9d4817f2480ec075bc6385d8d28ff4da94b
@@ -1,3 +1 @@
1
- <svg version="1.1" baseProfile="full" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
2
- <polyline points="9 2, 9 12, 4 12, 11 21, 13 21, 20 12, 15 12, 15 2, 9 2" fill="#822" stroke="#844" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
3
- </svg>
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><polyline points="9 2, 9 12, 4 12, 11 21, 13 21, 20 12, 15 12, 15 2, 9 2" fill="#822" stroke="#844" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /></svg>
@@ -1,3 +1 @@
1
- <svg version="1.1" baseProfile="full" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
2
- <polyline points="9 2, 9 12, 4 12, 11 21, 13 21, 20 12, 15 12, 15 2, 9 2" fill="#888" stroke="#444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
3
- </svg>
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><polyline points="9 2, 9 12, 4 12, 11 21, 13 21, 20 12, 15 12, 15 2, 9 2" fill="#888" stroke="#444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /></svg>
@@ -1,3 +1 @@
1
- <svg version="1.1" baseProfile="full" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
2
- <polyline points="9 2, 9 12, 4 12, 11 21, 13 21, 20 12, 15 12, 15 2, 9 2" fill="#ff4" stroke="#884" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
3
- </svg>
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><polyline points="9 2, 9 12, 4 12, 11 21, 13 21, 20 12, 15 12, 15 2, 9 2" fill="#ff4" stroke="#884" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /></svg>
@@ -1,3 +1 @@
1
- <svg version="1.1" baseProfile="full" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
2
- <polyline points="9 2, 9 12, 4 12, 11 21, 13 21, 20 12, 15 12, 15 2, 9 2" fill="none" stroke="#844" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
3
- </svg>
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><polyline points="9 2, 9 12, 4 12, 11 21, 13 21, 20 12, 15 12, 15 2, 9 2" fill="none" stroke="#844" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /></svg>
@@ -1,3 +1 @@
1
- <svg version="1.1" baseProfile="full" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
2
- <polyline points="9 21, 9 11, 4 11, 11 2, 13 2, 20 11, 15 11, 15 21, 9 21" fill="#282" stroke="#484" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
3
- </svg>
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><polyline points="9 21, 9 11, 4 11, 11 2, 13 2, 20 11, 15 11, 15 21, 9 21" fill="#282" stroke="#484" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /></svg>
@@ -1,3 +1 @@
1
- <svg version="1.1" baseProfile="full" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
2
- <polyline points="9 21, 9 11, 4 11, 11 2, 13 2, 20 11, 15 11, 15 21, 9 21" fill="#888" stroke="#444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
3
- </svg>
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><polyline points="9 21, 9 11, 4 11, 11 2, 13 2, 20 11, 15 11, 15 21, 9 21" fill="#888" stroke="#444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /></svg>
@@ -1,3 +1 @@
1
- <svg version="1.1" baseProfile="full" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
2
- <polyline points="9 21, 9 11, 4 11, 11 2, 13 2, 20 11, 15 11, 15 21, 9 21" fill="#ff4" stroke="#884" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
3
- </svg>
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><polyline points="9 21, 9 11, 4 11, 11 2, 13 2, 20 11, 15 11, 15 21, 9 21" fill="#ff4" stroke="#884" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /></svg>
@@ -1,3 +1 @@
1
- <svg version="1.1" baseProfile="full" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
2
- <polyline points="9 21, 9 11, 4 11, 11 2, 13 2, 20 11, 15 11, 15 21, 9 21" fill="none" stroke="#484" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
3
- </svg>
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><polyline points="9 21, 9 11, 4 11, 11 2, 13 2, 20 11, 15 11, 15 21, 9 21" fill="none" stroke="#484" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /></svg>
@@ -16,9 +16,9 @@ document.addEventListener('DOMContentLoaded', function () {
16
16
  const result = JSON.parse(this.responseText);
17
17
 
18
18
  $button.classList.remove('switch');
19
- if (result.hasOwnProperty('data')) {
20
- const vote_type = result['data']['vote_type'];
21
- const vote_result = result['data']['vote_result'];
19
+ if (result.hasOwnProperty('meta')) {
20
+ const vote_type = result['meta']['vote_type'];
21
+ const vote_result = result['meta']['vote_result'];
22
22
 
23
23
  $container.classList.remove('voted-none');
24
24
  $container.classList.add('voted-' + vote_type);
@@ -26,7 +26,7 @@ document.addEventListener('DOMContentLoaded', function () {
26
26
  }
27
27
  };
28
28
 
29
- const on_failure = function(result) {
29
+ const on_failure = function (result) {
30
30
  $button.classList.remove('switch');
31
31
  $button.classList.add('error');
32
32
  handle_ajax_failure(result);
@@ -42,4 +42,56 @@ document.addEventListener('DOMContentLoaded', function () {
42
42
  $container.classList.remove('active');
43
43
  });
44
44
  });
45
+
46
+ document.querySelectorAll('[data-vote]').forEach(function (button) {
47
+ const container = button.closest('[data-vote-url]');
48
+ if (container) {
49
+ if (container.classList.contains('vote-active')) {
50
+ const url = container.getAttribute('data-vote-url');
51
+
52
+ button.addEventListener('click', function () {
53
+ const delta = this.getAttribute('data-vote') === 'up' ? 1 : -1;
54
+ const pressedButton = this;
55
+
56
+ /**
57
+ * Во время голосования состояние переключается
58
+ * на vote-inactive, поэтому проверяем ещё раз
59
+ */
60
+ if (container.classList.contains('vote-active')) {
61
+ const data = {
62
+ vote: {
63
+ votable_id: container.getAttribute('data-votable-id'),
64
+ votable_type: container.getAttribute('data-votable-type'),
65
+ delta: delta,
66
+ }
67
+ };
68
+
69
+ const request = Biovision.jsonAjaxRequest('POST', url, function () {
70
+ if (this.responseText) {
71
+ const response = JSON.parse(this.responseText);
72
+
73
+ if (response.hasOwnProperty('meta')) {
74
+ if (delta > 0) {
75
+ pressedButton.innerHTML = response.meta['upvote_count'];
76
+ } else {
77
+ pressedButton.innerHTML = response.meta['downvote_count'];
78
+ }
79
+ container.classList.remove('voted-none');
80
+ container.classList.add('voted-' + response.meta['vote_type']);
81
+ }
82
+ } else {
83
+ container.classList.remove('vote-inactive');
84
+ container.classList.add('vote-active');
85
+ }
86
+ });
87
+
88
+ container.classList.remove('vote-active');
89
+ container.classList.add('vote-inactive');
90
+
91
+ request.send(JSON.stringify(data));
92
+ }
93
+ });
94
+ }
95
+ }
96
+ });
45
97
  });
@@ -4,10 +4,10 @@ class VotesController < ApplicationController
4
4
  # post /votes
5
5
  def create
6
6
  @entity = Vote.new(creation_parameters)
7
- if @entity.votable.votable_by?(current_user)
7
+ if @entity.votable.vote_applicable?(@entity)
8
8
  process_vote
9
9
  else
10
- render :result, status: :unauthorized
10
+ render :result, status: :unprocessable_entity
11
11
  end
12
12
  end
13
13
 
@@ -32,7 +32,7 @@ class VotesController < ApplicationController
32
32
  end
33
33
 
34
34
  def process_vote
35
- if Vote.voted?(current_user, @entity.votable)
35
+ if Vote.voted?(@entity.current_slug, @entity.votable)
36
36
  render :result, status: :conflict
37
37
  else
38
38
  count_vote
@@ -5,26 +5,26 @@ module VotableItem
5
5
  has_many :votes, as: :votable, dependent: :destroy
6
6
  end
7
7
 
8
- # @param [User] user
9
- def votable_by?(user)
10
- return false if user.nil?
11
- !Vote.voted?(user, self)
8
+ # @param [Vote|String] vote_or_slug
9
+ def vote_applicable?(vote_or_slug)
10
+ slug = vote_or_slug.is_a?(String) ? vote_or_slug : vote_or_slug.slug
11
+ !Vote.voted?(slug, self)
12
12
  end
13
13
 
14
- # @param [User] user
15
- def vote_data(user = nil)
14
+ # @param [String|Vote] vote_or_slug
15
+ def vote_data(vote_or_slug)
16
16
  {
17
17
  upvote_count: upvote_count,
18
18
  downvote_count: downvote_count,
19
19
  vote_result: vote_result,
20
- vote_type: voted(user)
20
+ vote_type: voted(vote_or_slug)
21
21
  }
22
22
  end
23
23
 
24
- # @param [User] user
25
- def voted(user)
26
- vote = votes.find_by(user: user)
27
- return :none if vote.nil?
24
+ # @param [String|Vote] vote_or_slug
25
+ def voted(vote_or_slug)
26
+ vote = vote_or_slug.is_a?(String) ? votes.find_by(slug: vote_or_slug) : vote_or_slug
27
+ return :none if vote&.id.nil?
28
28
  vote.upvote? ? :upvote : :downvote
29
29
  end
30
30
  end
data/app/models/vote.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  class Vote < ApplicationRecord
2
2
  include HasOwner
3
3
 
4
- PER_PAGE = 20
5
-
6
4
  METRIC_VOTE_HIT = 'votes.any.hit'
7
5
  METRIC_UPVOTE_HIT = 'votes.upvote.hit'
8
6
  METRIC_DOWNVOTE_HIT = 'votes.downvote.hit'
@@ -12,22 +10,35 @@ class Vote < ApplicationRecord
12
10
  belongs_to :votable, polymorphic: true
13
11
 
14
12
  before_validation { self.delta = (delta.to_i > 0 ? 1 : -1) }
15
- validates_uniqueness_of :votable_id, scope: [:user_id, :votable_type]
13
+ before_validation :generate_slug
14
+ validates_uniqueness_of :votable_id, scope: [:slug, :votable_type]
16
15
 
17
16
  after_create :add_vote_result
18
17
  after_destroy :discard_vote_result
19
18
 
20
19
  scope :recent, -> { order('id desc') }
20
+ scope :list_for_administration, -> { recent }
21
21
 
22
22
  # @param [Integer] page
23
23
  def self.page_for_administration(page = 1)
24
- recent.page(page).per(PER_PAGE)
24
+ list_for_administration.page(page)
25
25
  end
26
26
 
27
27
  # @param [User] user
28
+ # @param [String] ip
29
+ # @param [Integer] agent_id
30
+ def self.slug_string(user, ip, agent_id)
31
+ if user.nil?
32
+ "#{ip}:#{agent_id}"
33
+ else
34
+ user.id.to_s
35
+ end
36
+ end
37
+
38
+ # @param [String] slug
28
39
  # @param [ApplicationRecord] votable
29
- def self.voted?(user, votable)
30
- exists?(user: user, votable: votable)
40
+ def self.voted?(slug, votable)
41
+ exists?(slug: slug, votable: votable)
31
42
  end
32
43
 
33
44
  # @param [User] user
@@ -56,8 +67,16 @@ class Vote < ApplicationRecord
56
67
  owned_by?(user) || UserPrivilege.user_has_privilege?(:user, :moderator)
57
68
  end
58
69
 
70
+ def current_slug
71
+ self.class.slug_string(user, ip, agent_id)
72
+ end
73
+
59
74
  private
60
75
 
76
+ def generate_slug
77
+ self.slug = current_slug
78
+ end
79
+
61
80
  def add_vote_result
62
81
  votable.vote_result = votable.vote_result + delta
63
82
  votable.upvote_count = votable.upvote_count + 1 if upvote?
@@ -0,0 +1,10 @@
1
+ <% if current_user_has_privilege?(:moderator) %>
2
+ <nav>
3
+ <div class="heading" id="biovision-vote-nav-heading">
4
+ <%= t('.heading') %>
5
+ </div>
6
+ <ul aria-labelledby="biovision-vote-nav-heading">
7
+ <li><%= render 'admin/votes/nav_item' %></li>
8
+ </ul>
9
+ </nav>
10
+ <% end %>
@@ -1,6 +1,2 @@
1
- <div>
2
- <%= link_to t('.text'), admin_votes_path %>
3
- </div>
4
- <div class="description">
5
- <%= t('.description') %>
6
- </div>
1
+ <div><%= link_to t('.text'), admin_votes_path %></div>
2
+ <div class="description"><%= t('.description') %></div>
@@ -2,13 +2,8 @@
2
2
  <%= vote_image(entity) %>
3
3
  </div>
4
4
  <div class="data">
5
- <div>
6
- <%= biovision_votable_link(entity.votable) %>
7
- </div>
8
- <div class="info">
9
- <%= admin_user_link(entity.user) %>
10
- </div>
11
- <div class="secondary info">
12
- <%= time_tag(entity.created_at) %>
13
- </div>
5
+ <div><%= biovision_votable_link(entity.votable) %></div>
6
+ <div class="info"><%= admin_user_link(entity.user) %></div>
7
+ <div class="secondary info"><%= entity.slug %></div>
8
+ <div class="secondary info"><%= time_tag(entity.created_at) %></div>
14
9
  </div>
@@ -1,5 +1,8 @@
1
- <% block_class = votable.votable_by?(current_user) ? 'active' : '' %>
2
- <div class="vote-block <%= block_class %> voted-<%= votable.voted(current_user) %>" data-id="<%= votable.id %>">
1
+ <%
2
+ slug = Vote.slug_string(current_user, request.env['HTTP_X_REAL_IP'] || request.remote_ip, agent.id)
3
+ block_class = votable.vote_applicable?(slug) ? 'active' : ''
4
+ %>
5
+ <div class="vote-block <%= block_class %> voted-<%= votable.voted(slug) %>" data-id="<%= votable.id %>">
3
6
  <div class="vote upvote"></div>
4
7
  <div class="result"><%= votable.vote_result %></div>
5
8
  <div class="vote downvote"></div>
@@ -1 +1 @@
1
- json.data @entity.votable.vote_data(current_user)
1
+ json.meta @entity.votable.vote_data(@entity)
@@ -0,0 +1,37 @@
1
+ en:
2
+ upvote_count:
3
+ zero: "no upvotes"
4
+ one: "%{count} upvote"
5
+ few: "%{count} upvotes"
6
+ many: "%{count} upvotes"
7
+ other: "%{count} upvotes"
8
+ downvote_count:
9
+ zero: "no downvotes"
10
+ one: "%{count} downvote"
11
+ few: "%{count} downvotes"
12
+ many: "%{count} downvotes"
13
+ other: "%{count} downvotes"
14
+ activerecord:
15
+ models:
16
+ vote: "Vote"
17
+ attributes:
18
+ vote:
19
+ agent: "User agent"
20
+ delta: "Delta"
21
+ ip: "IP address"
22
+ slug: "Slug"
23
+ user: "User"
24
+ votable: "Votable entity"
25
+ votable_id: "Votable entity"
26
+ admin:
27
+ votes:
28
+ nav_item:
29
+ description: "Manage user votes"
30
+ text: "User votes"
31
+ index:
32
+ heading: "User votes"
33
+ title: "User votes, page %{page}"
34
+ index:
35
+ dashboard:
36
+ biovision_vote:
37
+ heading: "User votes"
@@ -16,16 +16,22 @@ ru:
16
16
  vote: "Голос"
17
17
  attributes:
18
18
  vote:
19
- user: "Пользователь"
20
- votable: "Объект голосования"
21
19
  agent: "Агент пользователя"
22
- ip: "IP-адрес"
23
20
  delta: "Изменение"
21
+ ip: "IP-адрес"
22
+ slug: "Идентификатор"
23
+ user: "Пользователь"
24
+ votable: "Объект голосования"
25
+ votable_id: "Объект голосования"
24
26
  admin:
25
27
  votes:
26
28
  nav_item:
27
- text: "Голоса пользователей"
28
29
  description: "Просмотр голосов пользователей"
30
+ text: "Голоса пользователей"
29
31
  index:
30
- title: "Голоса, страница %{page}"
31
32
  heading: "Голоса пользователей"
33
+ title: "Голоса, страница %{page}"
34
+ index:
35
+ dashboard:
36
+ biovision_vote:
37
+ heading: "Голоса пользователей"
data/config/routes.rb CHANGED
@@ -1,7 +1,11 @@
1
1
  Rails.application.routes.draw do
2
- resources :votes, only: [:create, :destroy], defaults: { format: :json }
2
+ resources :votes, only: [:destroy], defaults: { format: :json }
3
3
 
4
- namespace :admin do
5
- resources :votes, only: [:index]
4
+ scope '(:locale)', constraints: { locale: /ru|en/ } do
5
+ resources :votes, only: [:create], defaults: { format: :json }
6
+
7
+ namespace :admin do
8
+ resources :votes, only: [:index]
9
+ end
6
10
  end
7
11
  end
@@ -1,13 +1,22 @@
1
- class CreateVotes < ActiveRecord::Migration[5.0]
2
- def change
3
- create_table :votes do |t|
4
- t.timestamps
5
- t.references :user, foreign_key: true, on_update: :cascade, on_delete: :cascade
6
- t.references :agent, foreign_key: true, on_update: :cascade, on_delete: :nullify
7
- t.inet :ip
8
- t.integer :delta, limit: 2, default: 0, null: false
9
- t.integer :votable_id, null: false
10
- t.string :votable_type, null: false
1
+ class CreateVotes < ActiveRecord::Migration[5.1]
2
+ def up
3
+ unless Vote.table_exists?
4
+ create_table :votes do |t|
5
+ t.timestamps
6
+ t.references :user, foreign_key: true, on_update: :cascade, on_delete: :cascade
7
+ t.references :agent, foreign_key: true, on_update: :cascade, on_delete: :nullify
8
+ t.inet :ip
9
+ t.integer :delta, limit: 2, default: 0, null: false
10
+ t.integer :votable_id, null: false
11
+ t.string :votable_type, null: false
12
+ t.string :slug, index: true
13
+ end
14
+ end
15
+ end
16
+
17
+ def down
18
+ if Vote.table_exists?
19
+ drop_table :votes
11
20
  end
12
21
  end
13
22
  end
@@ -0,0 +1,15 @@
1
+ class AddSlugToVotes < ActiveRecord::Migration[5.2]
2
+ def up
3
+ unless column_exists?(:votes, :slug)
4
+ add_column :votes, :slug, :string, index: true
5
+
6
+ Vote.order('id asc').each do |vote|
7
+ vote.update! slug: vote.current_slug
8
+ end
9
+ end
10
+ end
11
+
12
+ def down
13
+ # No need to rollback
14
+ end
15
+ end
@@ -7,7 +7,7 @@ module Biovision
7
7
 
8
8
  config.generators do |g|
9
9
  g.test_framework :rspec
10
- g.fixture_replacement :factory_girl, :dir => 'spec/factories'
10
+ g.fixture_replacement :factory_bot, :dir => 'spec/factories'
11
11
  end
12
12
  end
13
13
  end
@@ -1,5 +1,5 @@
1
1
  module Biovision
2
2
  module Vote
3
- VERSION = '0.1.2.170925'
3
+ VERSION = '0.2.180610'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: biovision-vote
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.170925
4
+ version: 0.2.180610
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxim Khan-Magomedov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-25 00:00:00.000000000 Z
11
+ date: 2018-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: factory_girl_rails
112
+ name: factory_bot_rails
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -154,15 +154,18 @@ files:
154
154
  - app/models/biovision/vote/application_record.rb
155
155
  - app/models/concerns/votable_item.rb
156
156
  - app/models/vote.rb
157
+ - app/views/admin/index/dashboard/_biovision_vote.html.erb
157
158
  - app/views/admin/votes/_nav_item.html.erb
158
159
  - app/views/admin/votes/entity/_in_list.html.erb
159
160
  - app/views/admin/votes/index.html.erb
160
161
  - app/views/layouts/biovision/vote/application.html.erb
161
162
  - app/views/votes/_vote_block.html.erb
162
163
  - app/views/votes/result.jbuilder
164
+ - config/locales/votes-en.yml
163
165
  - config/locales/votes-ru.yml
164
166
  - config/routes.rb
165
167
  - db/migrate/20170330000001_create_votes.rb
168
+ - db/migrate/20180610110015_add_slug_to_votes.rb
166
169
  - lib/biovision/vote.rb
167
170
  - lib/biovision/vote/engine.rb
168
171
  - lib/biovision/vote/version.rb
@@ -187,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
190
  version: '0'
188
191
  requirements: []
189
192
  rubyforge_project:
190
- rubygems_version: 2.6.13
193
+ rubygems_version: 2.7.6
191
194
  signing_key:
192
195
  specification_version: 4
193
196
  summary: Voting functionality for biovision-based applications