voluntary_ranking 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +29 -0
- data/app/assets/javascripts/voluntary_ranking/app.js +11 -0
- data/app/assets/javascripts/voluntary_ranking/application.js +4 -0
- data/app/assets/javascripts/voluntary_ranking/base.js.coffee +3 -0
- data/app/assets/javascripts/voluntary_ranking/components/modal_dialog_component.js.coffee +6 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/arguments/index_controller.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/arguments/new_controller.js.coffee +16 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/compare_things/arguments_controller.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/compare_things_controller.js.coffee +8 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/controller.js.coffee +1 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/index_controller.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/profile/rankings_controller.js.coffee +3 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/ranking_item_controller.js.coffee +7 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/rankings/index_controller.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/rankings/show_controller.js.coffee +6 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/thing_controller.js.coffee +10 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/user/rankings/show_controller.js.coffee +92 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/user_controller.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_ranking/controllers/user_ranking_controller.js.coffee +2 -0
- data/app/assets/javascripts/voluntary_ranking/helpers/name_with_apostrophe_helper.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_ranking/helpers/stars_html_helper.js.coffee +29 -0
- data/app/assets/javascripts/voluntary_ranking/mixins/has_current_user.js.coffee +4 -0
- data/app/assets/javascripts/voluntary_ranking/mixins/pagination_controller.js.coffee +51 -0
- data/app/assets/javascripts/voluntary_ranking/mixins/ranking_controller.js.coffee +31 -0
- data/app/assets/javascripts/voluntary_ranking/mixins/singleton.js.coffee +17 -0
- data/app/assets/javascripts/voluntary_ranking/models/argument.js.coffee +7 -0
- data/app/assets/javascripts/voluntary_ranking/models/movie.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_ranking/models/ranking.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_ranking/models/ranking_item.js.coffee +26 -0
- data/app/assets/javascripts/voluntary_ranking/models/thing.js.coffee +2 -0
- data/app/assets/javascripts/voluntary_ranking/models/user.js.coffee +18 -0
- data/app/assets/javascripts/voluntary_ranking/models/user/ranking_item.js.coffee +33 -0
- data/app/assets/javascripts/voluntary_ranking/router.js.coffee +30 -0
- data/app/assets/javascripts/voluntary_ranking/routes/arguments/index_route.js.coffee +24 -0
- data/app/assets/javascripts/voluntary_ranking/routes/compare_things/arguments_route.js.coffee +16 -0
- data/app/assets/javascripts/voluntary_ranking/routes/compare_things/compare_things_route.js.coffee +9 -0
- data/app/assets/javascripts/voluntary_ranking/routes/profile/rankings_route.js.coffee +29 -0
- data/app/assets/javascripts/voluntary_ranking/routes/ranking_item_route.js.coffee +25 -0
- data/app/assets/javascripts/voluntary_ranking/routes/rankings/index_route.js.coffee +10 -0
- data/app/assets/javascripts/voluntary_ranking/routes/rankings/show_route.js.coffee +19 -0
- data/app/assets/javascripts/voluntary_ranking/routes/thing_route.js.coffee +7 -0
- data/app/assets/javascripts/voluntary_ranking/routes/user_ranking_route.js.coffee +27 -0
- data/app/assets/javascripts/voluntary_ranking/routes/user_route.js.coffee +20 -0
- data/app/assets/javascripts/voluntary_ranking/templates/application.handlebars.erb +16 -0
- data/app/assets/javascripts/voluntary_ranking/templates/arguments.js.handlebars +1 -0
- data/app/assets/javascripts/voluntary_ranking/templates/arguments/index.js.handlebars +27 -0
- data/app/assets/javascripts/voluntary_ranking/templates/arguments/new.js.handlebars +17 -0
- data/app/assets/javascripts/voluntary_ranking/templates/compare_things.js.handlebars +22 -0
- data/app/assets/javascripts/voluntary_ranking/templates/compare_things/arguments.js.handlebars +26 -0
- data/app/assets/javascripts/voluntary_ranking/templates/components/modal-dialog.js.handlebars +9 -0
- data/app/assets/javascripts/voluntary_ranking/templates/components/rankings-component.handlebars +17 -0
- data/app/assets/javascripts/voluntary_ranking/templates/index.js.handlebars +1 -0
- data/app/assets/javascripts/voluntary_ranking/templates/navigation.js.handlebars +28 -0
- data/app/assets/javascripts/voluntary_ranking/templates/ranking_item.js.handlebars +31 -0
- data/app/assets/javascripts/voluntary_ranking/templates/ranking_items/_collection.js.handlebars +84 -0
- data/app/assets/javascripts/voluntary_ranking/templates/ranking_items/_form.js.handlebars +30 -0
- data/app/assets/javascripts/voluntary_ranking/templates/rankings/_form.js.handlebars +38 -0
- data/app/assets/javascripts/voluntary_ranking/templates/rankings/index.js.handlebars +3 -0
- data/app/assets/javascripts/voluntary_ranking/templates/rankings/show.js.handlebars +3 -0
- data/app/assets/javascripts/voluntary_ranking/templates/shared/_pagination.js.handlebars +23 -0
- data/app/assets/javascripts/voluntary_ranking/templates/shared/_stars.js.handlebars +3 -0
- data/app/assets/javascripts/voluntary_ranking/templates/thing.js.handlebars +13 -0
- data/app/assets/javascripts/voluntary_ranking/templates/thing/index.js.handlebars +0 -0
- data/app/assets/javascripts/voluntary_ranking/templates/things/show.arguments.js.handlebars +1 -0
- data/app/assets/javascripts/voluntary_ranking/templates/things/show.js.handlebars +1 -0
- data/app/assets/javascripts/voluntary_ranking/templates/user.js.handlebars +5 -0
- data/app/assets/javascripts/voluntary_ranking/templates/user/rankings/details.js.handlebars +7 -0
- data/app/assets/javascripts/voluntary_ranking/views/application/index_view.js.coffee +1 -0
- data/app/assets/javascripts/voluntary_ranking/views/arguments/new_view.js.coffee +9 -0
- data/app/assets/javascripts/voluntary_ranking/views/index_view.js.coffee +1 -0
- data/app/assets/javascripts/voluntary_ranking/views/ranking_items/colllection_view.js.coffee +25 -0
- data/app/assets/javascripts/voluntary_ranking/views/shared/pagination.js +4 -0
- data/app/assets/stylesheets/voluntary_ranking/application.css +17 -0
- data/app/assets/stylesheets/voluntary_ranking/base.css.sass +6 -0
- data/app/assets/stylesheets/voluntary_ranking/bootstrap_and_overrides.css.sass +0 -0
- data/app/assets/stylesheets/voluntary_ranking/stars.css.sass +31 -0
- data/app/assets/stylesheets/voluntary_ranking/twitter-typeahead.css.sass +29 -0
- data/app/controllers/api/v1/argument_topics_controller.rb +12 -0
- data/app/controllers/api/v1/arguments_controller.rb +32 -0
- data/app/controllers/api/v1/ranking_items_controller.rb +43 -0
- data/app/controllers/api/v1/rankings_controller.rb +29 -0
- data/app/controllers/api/v1/things/arguments_controller.rb +40 -0
- data/app/controllers/api/v1/things_controller.rb +26 -0
- data/app/controllers/api/v1/user_ranking_items_controller.rb +94 -0
- data/app/controllers/api/v1/users_controller.rb +9 -0
- data/app/controllers/product/ranking_controller.rb +16 -0
- data/app/models/argument.rb +48 -0
- data/app/models/argument_topic.rb +7 -0
- data/app/models/product/ranking.rb +2 -0
- data/app/models/ranking.rb +97 -0
- data/app/models/ranking_item.rb +30 -0
- data/app/models/user_ranking_item.rb +136 -0
- data/app/serializers/argument_serializer.rb +11 -0
- data/app/serializers/base_ranking_item_serializer.rb +23 -0
- data/app/serializers/ranking_item_serializer.rb +2 -0
- data/app/serializers/user_ranking_item_serializer.rb +7 -0
- data/app/views/product/ranking/index.html.erb +0 -0
- data/config/locales/en.yml +10 -0
- data/config/locales/resources/ranking/en.yml +10 -0
- data/config/routes.rb +41 -0
- data/db/migrate/20130817115303_add_ranking_product.rb +50 -0
- data/db/migrate/20140926102943_create_arguments.rb +20 -0
- data/lib/concerns/controller/base_ranking_items_controller.rb +10 -0
- data/lib/concerns/model/base_ranking_item.rb +29 -0
- data/lib/concerns/model/user/ranking.rb +48 -0
- data/lib/tasks/voluntary_ranking_tasks.rake +4 -0
- data/lib/voluntary_ranking.rb +12 -0
- data/lib/voluntary_ranking/ability.rb +11 -0
- data/lib/voluntary_ranking/engine.rb +16 -0
- data/lib/voluntary_ranking/version.rb +3 -0
- metadata +436 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class RankingItem < ActiveRecord::Base
|
|
2
|
+
include Concerns::Model::BaseRankingItem
|
|
3
|
+
|
|
4
|
+
attr_accessible :ranking_id, :thing, :thing_id, :best, :stars
|
|
5
|
+
|
|
6
|
+
has_many :user_ranking_items, dependent: :destroy
|
|
7
|
+
|
|
8
|
+
validates :thing_id, presence: true, uniqueness: { scope: :ranking_id }
|
|
9
|
+
|
|
10
|
+
acts_as_list scope: :ranking_id
|
|
11
|
+
|
|
12
|
+
def update_position
|
|
13
|
+
other_ranking_item = RankingItem.where(
|
|
14
|
+
'ranking_id = ? AND stars_sum >= ? AND id <> ?', ranking_id, stars_sum, id
|
|
15
|
+
).order('position DESC').first
|
|
16
|
+
|
|
17
|
+
if other_ranking_item
|
|
18
|
+
if RankingItem.where(ranking_id: ranking_id).count >= other_ranking_item.position + 1
|
|
19
|
+
#puts "update_position.1.1 (#{thing.name} with #{stars_sum}): #{other_ranking_item.position + 1}"
|
|
20
|
+
insert_at other_ranking_item.position + 1
|
|
21
|
+
else
|
|
22
|
+
#puts "update_position.1.2 (#{thing.name} with #{stars_sum}): #{other_ranking_item.position}"
|
|
23
|
+
insert_at other_ranking_item.position
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
#puts "update_position.2 (#{thing.name} with #{stars_sum}): 1"
|
|
27
|
+
insert_at 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
class UserRankingItem < ActiveRecord::Base
|
|
2
|
+
include Concerns::Model::BaseRankingItem
|
|
3
|
+
|
|
4
|
+
attr_accessible :ranking, :ranking_id, :thing, :thing_id, :best, :stars
|
|
5
|
+
|
|
6
|
+
belongs_to :user
|
|
7
|
+
belongs_to :ranking_item, counter_cache: true
|
|
8
|
+
|
|
9
|
+
validates :user_id, presence: true
|
|
10
|
+
validates :ranking_item_id, presence: true, uniqueness: { scope: [:user_id] }
|
|
11
|
+
validates :stars, presence: true
|
|
12
|
+
validate :stars_and_best
|
|
13
|
+
|
|
14
|
+
after_validation :copy_validation_errors_from_ranking_item # or before?
|
|
15
|
+
after_create :add_stars_to_ranking_item
|
|
16
|
+
after_update :remove_or_add_stars_to_ranking_item, if: 'stars_changed?'
|
|
17
|
+
|
|
18
|
+
after_destroy :destroy_ranking_item, if: 'UserRankingItem.where(ranking_item_id: ranking_item_id).count == 0'
|
|
19
|
+
|
|
20
|
+
acts_as_list scope: [:user_id, :ranking_id]
|
|
21
|
+
|
|
22
|
+
def self.position_for_user_by_stars(user_id, ranking_id, user_ranking_item_id, stars)
|
|
23
|
+
ranking_items = where(user_id: user_id, ranking_id: ranking_id)
|
|
24
|
+
ranking_items_count = ranking_items.count
|
|
25
|
+
ranking_items = ranking_items.where('id <> ?', user_ranking_item_id) if user_ranking_item_id.present?
|
|
26
|
+
|
|
27
|
+
if stars.to_i >= 3
|
|
28
|
+
ranking_items.order('stars ASC, position DESC').where('stars >= ?', stars).first.try(:position).to_i + 1 || 1
|
|
29
|
+
else
|
|
30
|
+
item = ranking_items.order('stars DESC, position ASC').where('stars <= ?', stars).first
|
|
31
|
+
|
|
32
|
+
if item.present?
|
|
33
|
+
if user_ranking_item_id.present? && item.stars < stars
|
|
34
|
+
item.position - 1
|
|
35
|
+
else
|
|
36
|
+
item.position
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
position = ranking_items.order('stars ASC, position DESC').where('stars >= ?', stars).first.try(:position).to_i + 1
|
|
40
|
+
|
|
41
|
+
position -= 1 if user_ranking_item_id.present? && position > ranking_items_count
|
|
42
|
+
|
|
43
|
+
position
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def move_to_top_of_page(page)
|
|
49
|
+
item_on_top_of_page = user.ranking_items.where(ranking_id: ranking_id).order('position').paginate(page: page, per_page: 10).first
|
|
50
|
+
self.stars = item_on_top_of_page.stars
|
|
51
|
+
self.best = item_on_top_of_page.best
|
|
52
|
+
insert_at(item_on_top_of_page.position)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def set_position(value)
|
|
56
|
+
item = UserRankingItem.where(
|
|
57
|
+
'ranking_id = :ranking_id AND position = :position', ranking_id: ranking_id, position: value
|
|
58
|
+
).first
|
|
59
|
+
|
|
60
|
+
self.stars = item.stars; self.best = item.best;
|
|
61
|
+
|
|
62
|
+
insert_at(value)
|
|
63
|
+
|
|
64
|
+
reload
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def update_stars(stars)
|
|
68
|
+
self.stars = stars
|
|
69
|
+
self.best = stars >= 3
|
|
70
|
+
save!
|
|
71
|
+
insert_at UserRankingItem.position_for_user_by_stars(user_id, ranking.id, id, stars)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def copy_validation_errors_from_ranking_item
|
|
77
|
+
return if self.ranking_item.blank? || self.ranking_item.valid?
|
|
78
|
+
|
|
79
|
+
self.ranking_item.errors.each do |field, ranking_item_errors|
|
|
80
|
+
ranking_item_errors = [ranking_item_errors] unless ranking_item_errors.is_a?(Array)
|
|
81
|
+
|
|
82
|
+
ranking_item_errors.each do |error|
|
|
83
|
+
unless attributes.has_key?(field.to_s)
|
|
84
|
+
field = :base
|
|
85
|
+
error = "#{field.to_s.humanize}: #{error}"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
self.errors[field] << error unless self.errors[field].include? error
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def stars_and_best
|
|
94
|
+
if self.stars >= 3 && !self.best
|
|
95
|
+
self.errors[:best] << 'Item cannot be worst with more stars than 3.'
|
|
96
|
+
elsif self.stars <= 2 && self.best
|
|
97
|
+
self.errors[:best] << 'Item cannot be best with less stars than 3.'
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def destroy_ranking_item
|
|
102
|
+
ranking_item.destroy
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def add_stars_to_ranking_item
|
|
106
|
+
ranking_item.stars_sum += stars
|
|
107
|
+
|
|
108
|
+
if ranking_item.stars_sum == 0
|
|
109
|
+
ranking_item.stars = 0
|
|
110
|
+
else
|
|
111
|
+
ranking_item.stars = (ranking_item.stars_sum / ranking_item.user_ranking_items_count).round
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
ranking_item.save
|
|
115
|
+
ranking_item.update_position
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def remove_or_add_stars_to_ranking_item
|
|
119
|
+
if stars > stars_was
|
|
120
|
+
#puts "remove_or_add_stars_to_ranking_item.1: #{ranking_item.stars_sum} += (#{stars} - #{stars_was})"
|
|
121
|
+
ranking_item.stars_sum += (stars - stars_was)
|
|
122
|
+
else
|
|
123
|
+
#puts "remove_or_add_stars_to_ranking_item.2: #{ranking_item.stars_sum} -= (#{stars_was} - #{stars})"
|
|
124
|
+
ranking_item.stars_sum -= (stars_was - stars)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
if ranking_item.stars_sum == 0
|
|
128
|
+
ranking_item.stars = 0
|
|
129
|
+
else
|
|
130
|
+
ranking_item.stars = (ranking_item.stars_sum / ranking_item.user_ranking_items_count).round
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
ranking_item.save
|
|
134
|
+
ranking_item.update_position
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class BaseRankingItemSerializer < ActiveModel::Serializer
|
|
2
|
+
attributes :id, :position, :thing_id, :thing_name, :best, :stars, :ranking_adjective, :ranking_negative_adjective, :ranking_topic, :ranking_scope
|
|
3
|
+
|
|
4
|
+
def thing_name
|
|
5
|
+
object.thing.name
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def ranking_adjective
|
|
9
|
+
object.ranking.adjective
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def ranking_negative_adjective
|
|
13
|
+
object.ranking.negative_adjective
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def ranking_topic
|
|
17
|
+
object.ranking.topic
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ranking_scope
|
|
21
|
+
object.ranking.scope
|
|
22
|
+
end
|
|
23
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
en:
|
|
2
|
+
activerecord:
|
|
3
|
+
errors:
|
|
4
|
+
models:
|
|
5
|
+
ranking:
|
|
6
|
+
attributes:
|
|
7
|
+
base:
|
|
8
|
+
one_ranking_per_topic_scope_and_one_of_the_adjectives: Only one ranking per topic, scope and one of the adjectives allowed!
|
|
9
|
+
name:
|
|
10
|
+
unwanted_special_characters_included: Name must not include slash.
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Rails.application.routes.draw do
|
|
2
|
+
get '/products/ranking' => 'product/ranking#index'
|
|
3
|
+
|
|
4
|
+
namespace :api, defaults: {format: 'json'} do
|
|
5
|
+
scope module: :v1, path: 'v1' do
|
|
6
|
+
# TODO: remove manual routing when get rid of this resource using root UsersController
|
|
7
|
+
resources :argument_topics, only: [] do
|
|
8
|
+
collection do
|
|
9
|
+
get :autocomplete
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
resources :arguments
|
|
14
|
+
|
|
15
|
+
resources :rankings
|
|
16
|
+
|
|
17
|
+
get '/rankings/attributes/:attribute/autocomplete', to: 'rankings#autocomplete_attribute'
|
|
18
|
+
|
|
19
|
+
resources :ranking_items
|
|
20
|
+
|
|
21
|
+
resources :things, only: [:show] do
|
|
22
|
+
collection do
|
|
23
|
+
get :autocomplete
|
|
24
|
+
get :suggest
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
get '/things/:left_thing_name/vs/:right_thing_name/arguments', to: 'things/arguments#comparison'
|
|
29
|
+
get '/things/:thing_name/is_one_of_the/:adjective/:topic/:scope', to: 'ranking_items#show'
|
|
30
|
+
|
|
31
|
+
resources :user_ranking_items do
|
|
32
|
+
member do
|
|
33
|
+
put :move_to_page
|
|
34
|
+
put :move
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
resources :users
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
class AddRankingProduct < ActiveRecord::Migration
|
|
2
|
+
def up
|
|
3
|
+
Product::Ranking.create(name: 'Ranking', text: 'Ranking')
|
|
4
|
+
|
|
5
|
+
create_table :rankings, force: true do |t|
|
|
6
|
+
t.string :adjective # best
|
|
7
|
+
t.string :topic
|
|
8
|
+
t.string :scope
|
|
9
|
+
t.string :negative_adjective # worst
|
|
10
|
+
t.timestamps
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
create_table :ranking_items, force: true do |t|
|
|
14
|
+
t.integer :position
|
|
15
|
+
t.integer :ranking_id
|
|
16
|
+
t.integer :thing_id
|
|
17
|
+
t.boolean :best
|
|
18
|
+
t.integer :user_ranking_items_count, default: 0
|
|
19
|
+
t.integer :stars_sum, default: 0
|
|
20
|
+
t.integer :stars, default: 0
|
|
21
|
+
t.timestamps
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
add_index :ranking_items, [:ranking_id, :thing_id], unique: true
|
|
25
|
+
add_index :ranking_items, [:ranking_id, :stars_sum]
|
|
26
|
+
add_index :ranking_items, [:ranking_id, :position]
|
|
27
|
+
|
|
28
|
+
create_table :user_ranking_items, force: true do |t|
|
|
29
|
+
t.integer :user_id
|
|
30
|
+
t.integer :ranking_item_id
|
|
31
|
+
t.integer :position
|
|
32
|
+
t.boolean :best
|
|
33
|
+
t.integer :stars, default: 0
|
|
34
|
+
t.integer :ranking_id # cache column
|
|
35
|
+
t.integer :thing_id # cache column
|
|
36
|
+
t.timestamps
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
add_index :user_ranking_items, [:user_id, :ranking_id, :thing_id], unique: true
|
|
40
|
+
add_index :user_ranking_items, [:user_id, :ranking_id, :position]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def down
|
|
44
|
+
Product::Ranking.first.destroy
|
|
45
|
+
|
|
46
|
+
[:rankings, :ranking_items, :user_ranking_items].each do |table|
|
|
47
|
+
drop_table table
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class CreateArguments < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :argument_topics do |t|
|
|
4
|
+
t.string :name
|
|
5
|
+
t.text :text
|
|
6
|
+
t.timestamps
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
add_index :argument_topics, :name, unique: true
|
|
10
|
+
|
|
11
|
+
create_table :arguments do |t|
|
|
12
|
+
t.integer :topic_id
|
|
13
|
+
t.integer :thing_id
|
|
14
|
+
t.string :value
|
|
15
|
+
t.timestamps
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
add_index :arguments, [:topic_id, :thing_id], unique: true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Concerns
|
|
2
|
+
module Controller
|
|
3
|
+
module BaseRankingItemsController
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
#def ranking; @ranking ||= Ranking.find_or_create_by_params(params); end
|
|
7
|
+
def ranking; @ranking ||= Ranking.find_by_params(params) end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Concerns
|
|
2
|
+
module Model
|
|
3
|
+
module BaseRankingItem
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
belongs_to :ranking
|
|
8
|
+
belongs_to :thing
|
|
9
|
+
|
|
10
|
+
validates :ranking_id, presence: true
|
|
11
|
+
validates :thing_id, presence: true
|
|
12
|
+
|
|
13
|
+
#pusherable "#{Rails.env}_channel"
|
|
14
|
+
|
|
15
|
+
def thing=(thing)
|
|
16
|
+
thing.save if thing.new_record?
|
|
17
|
+
|
|
18
|
+
self.thing_id = thing.id
|
|
19
|
+
|
|
20
|
+
if self.respond_to?(:ranking_item_id) && self.ranking.present?
|
|
21
|
+
self.ranking_item ||= self.ranking.items.find_or_create_by_thing_id(thing_id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
thing
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Concerns
|
|
2
|
+
module Model
|
|
3
|
+
module User
|
|
4
|
+
module Ranking
|
|
5
|
+
module AddThingToUserList
|
|
6
|
+
def << *args
|
|
7
|
+
thing = args.first
|
|
8
|
+
proxy_association.owner.user_list_items.create!(list: thing.class.list, thing: thing)
|
|
9
|
+
self
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
alias_method :create, :<<
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
extend ActiveSupport::Concern
|
|
16
|
+
|
|
17
|
+
included do
|
|
18
|
+
has_many :rankings, through: :ranking_items, dependent: :destroy
|
|
19
|
+
has_many :ranking_items, class_name: 'UserRankingItem', dependent: :destroy
|
|
20
|
+
has_many :things, extend: AddThingToUserList
|
|
21
|
+
|
|
22
|
+
def add_ranking_item(attributes)
|
|
23
|
+
ranking = ::Ranking.find_or_create_by_params(attributes)
|
|
24
|
+
thing = Thing.find_or_create_by(name: attributes[:thing_name])
|
|
25
|
+
ranking_item_attributes = {
|
|
26
|
+
thing_id: thing.id, best: attributes[:best], stars: attributes[:stars]
|
|
27
|
+
}
|
|
28
|
+
ranking_item = ranking.items.where(thing_id: ranking_item_attributes[:thing_id]).first_or_create
|
|
29
|
+
|
|
30
|
+
user_ranking_item = ranking_items.new(
|
|
31
|
+
ranking_item_attributes.merge(ranking_id: ranking.id)
|
|
32
|
+
)
|
|
33
|
+
user_ranking_item.ranking_item_id = ranking_item.id
|
|
34
|
+
|
|
35
|
+
position = UserRankingItem.position_for_user_by_stars id, ranking.id, nil, attributes[:stars]
|
|
36
|
+
|
|
37
|
+
begin
|
|
38
|
+
user_ranking_item.insert_at(position)
|
|
39
|
+
rescue ActiveRecord::RecordInvalid
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
user_ranking_item
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|