voluntary_brainstorming 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +3 -2
- data/app/assets/javascripts/voluntary_brainstorming/app.js.coffee +8 -0
- data/app/assets/javascripts/voluntary_brainstorming/application.js +4 -0
- data/app/assets/javascripts/voluntary_brainstorming/components/brainstorming_idea_argument_component.js.coffee +63 -0
- data/app/assets/javascripts/voluntary_brainstorming/components/brainstorming_idea_cell_component.js.coffee +34 -0
- data/app/assets/javascripts/voluntary_brainstorming/components/brainstorming_idea_vote_component.js.coffee +46 -0
- data/app/assets/javascripts/voluntary_brainstorming/controllers/brainstorming_controller.js.coffee +79 -0
- data/app/assets/javascripts/voluntary_brainstorming/controllers/user_brainstormings_controller.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_brainstorming/mixins/destroy_brainstorming.js.coffee +14 -0
- data/app/assets/javascripts/voluntary_brainstorming/mixins/pagination_controller.js.coffee +43 -0
- data/app/assets/javascripts/voluntary_brainstorming/models/brainstorming.js.coffee +6 -0
- data/app/assets/javascripts/voluntary_brainstorming/models/user.js.coffee +18 -0
- data/app/assets/javascripts/voluntary_brainstorming/router.js.coffee +9 -0
- data/app/assets/javascripts/voluntary_brainstorming/routes/brainstorming_route.js.coffee +37 -0
- data/app/assets/javascripts/voluntary_brainstorming/routes/edit_brainstorming_route.js.coffee +16 -0
- data/app/assets/javascripts/voluntary_brainstorming/routes/index_route.js.coffee +4 -0
- data/app/assets/javascripts/voluntary_brainstorming/routes/new_brainstorming_route.js.coffee +5 -0
- data/app/assets/javascripts/voluntary_brainstorming/routes/user_brainstormings_route.js.coffee +20 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/application.handlebars.erb +20 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/brainstorming.js.handlebars +77 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/brainstorming_form.js.handlebars +18 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/brainstorming_idea_form.js.handlebars +19 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/components/brainstorming-idea-argument.js.handlebars +86 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/components/brainstorming-idea-cell.js.handlebars +7 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/components/brainstorming-idea-vote.js.handlebars +6 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/edit_brainstorming.js.handlebars +3 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/navigation.js.handlebars +28 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/new_brainstorming.js.handlebars +3 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/shared/_pagination.js.handlebars +23 -0
- data/app/assets/javascripts/voluntary_brainstorming/templates/user_brainstormings.js.handlebars +33 -0
- data/app/assets/stylesheets/voluntary_brainstorming/application.css +13 -0
- data/app/controllers/product/brainstorming_controller.rb +16 -0
- data/app/controllers/voluntary/api/v1/brainstorming_idea_votes_controller.rb +38 -0
- data/app/controllers/voluntary/api/v1/brainstorming_ideas_controller.rb +66 -0
- data/app/controllers/voluntary/api/v1/brainstormings_controller.rb +70 -0
- data/app/models/brainstorming.rb +18 -0
- data/app/models/brainstorming_idea.rb +53 -0
- data/app/models/brainstorming_idea_vote.rb +32 -0
- data/app/models/product/brainstorming.rb +2 -0
- data/app/serializers/brainstorming_idea_serializer.rb +15 -0
- data/app/serializers/brainstorming_idea_vote_serializer.rb +11 -0
- data/app/serializers/brainstorming_serializer.rb +7 -0
- data/app/views/product/brainstorming/index.html.erb +0 -0
- data/config/locales/resources/brainstorming/en.yml +26 -0
- data/config/locales/resources/brainstorming_idea_votes/en.yml +18 -0
- data/config/locales/resources/brainstorming_ideas/en.yml +31 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20150818181847_add_brainstorming_product.rb +51 -0
- data/lib/voluntary_brainstorming.rb +5 -1
- data/lib/voluntary_brainstorming/concerns/model/argument/publishes_changes_to_brainstorming.rb +49 -0
- data/lib/voluntary_brainstorming/concerns/model/user/has_brainstormings.rb +17 -0
- data/lib/voluntary_brainstorming/engine.rb +13 -0
- data/lib/voluntary_brainstorming/version.rb +1 -1
- metadata +322 -37
- data/MIT-LICENSE +0 -20
@@ -0,0 +1,70 @@
|
|
1
|
+
class Voluntary::Api::V1::BrainstormingsController < ActionController::Base
|
2
|
+
include Voluntary::V1::BaseController
|
3
|
+
|
4
|
+
respond_to :json
|
5
|
+
|
6
|
+
def index
|
7
|
+
options = {}
|
8
|
+
|
9
|
+
user = User.friendly.find params[:user_slug]
|
10
|
+
collection = user.brainstormings
|
11
|
+
options[:json] = collection.paginate page: params[:page], per_page: 10
|
12
|
+
|
13
|
+
options[:meta] = {
|
14
|
+
pagination: {
|
15
|
+
total_pages: options[:json].total_pages, current_page: options[:json].current_page,
|
16
|
+
previous_page: options[:json].previous_page, next_page: options[:json].next_page
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
respond_with do |format|
|
21
|
+
format.json { render options }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def show
|
26
|
+
user = User.friendly.find(params[:user_slug])
|
27
|
+
|
28
|
+
respond_to do |format|
|
29
|
+
format.json do
|
30
|
+
render json: user.brainstormings.friendly.find(params[:id])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def create
|
36
|
+
brainstorming = current_user.brainstormings.create params[:brainstorming]
|
37
|
+
|
38
|
+
respond_to do |format|
|
39
|
+
format.json do
|
40
|
+
render json: brainstorming.persisted? ? brainstorming : { errors: brainstorming.errors.to_hash }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def update
|
46
|
+
brainstorming = current_user.brainstormings.friendly.find params[:id]
|
47
|
+
brainstorming.update_attributes params[:brainstorming]
|
48
|
+
|
49
|
+
respond_to do |format|
|
50
|
+
format.json do
|
51
|
+
render json: brainstorming.valid? ? brainstorming : { errors: brainstorming.errors.to_hash }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def destroy
|
57
|
+
brainstorming = current_user.brainstormings.friendly.find params[:id]
|
58
|
+
brainstorming.destroy
|
59
|
+
|
60
|
+
respond_to do |format|
|
61
|
+
format.json do
|
62
|
+
render json: if brainstorming.persisted?
|
63
|
+
{ error: I18n.t('activerecord.errors.models.brainstorming.attributes.base.deletion_failed') }
|
64
|
+
else
|
65
|
+
{}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Brainstorming < ActiveRecord::Base
|
2
|
+
extend FriendlyId
|
3
|
+
|
4
|
+
belongs_to :user
|
5
|
+
|
6
|
+
has_many :ideas, class_name: 'BrainstormingIdea', dependent: :destroy
|
7
|
+
|
8
|
+
friendly_id :name, use: :scoped, scope: :user
|
9
|
+
|
10
|
+
attr_accessible :name, :text
|
11
|
+
|
12
|
+
validates :user_id, presence: true
|
13
|
+
validates :name, presence: true, uniqueness: { scope: :user_id }
|
14
|
+
|
15
|
+
def should_generate_new_friendly_id?
|
16
|
+
slug.blank? || name_changed?
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class BrainstormingIdea < ActiveRecord::Base
|
2
|
+
belongs_to :brainstorming
|
3
|
+
belongs_to :user
|
4
|
+
|
5
|
+
has_many :arguments, as: :argumentable, dependent: :destroy
|
6
|
+
has_many :votes, class_name: 'BrainstormingIdeaVote', dependent: :destroy, foreign_key: 'idea_id'
|
7
|
+
|
8
|
+
scope :with_current_user_vote, ->(user_id) do
|
9
|
+
select('brainstorming_ideas.*, brainstorming_idea_votes.user_id').joins(
|
10
|
+
'LEFT JOIN brainstorming_idea_votes ON brainstorming_idea_votes.idea_id = brainstorming_ideas.id AND ' +
|
11
|
+
"brainstorming_idea_votes.user_id = #{sanitize(user_id)}"
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
validates :brainstorming_id, presence: true
|
16
|
+
validates :user_id, presence: true
|
17
|
+
validates :name, presence: true, uniqueness: { scope: :brainstorming_id }
|
18
|
+
|
19
|
+
attr_accessible :brainstorming_id, :name, :text
|
20
|
+
|
21
|
+
after_create :publish_create
|
22
|
+
after_update :publish_update
|
23
|
+
after_destroy :publish_destroy
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def publish_create
|
28
|
+
return if Rails.env.test? || Rails.env.cucumber?
|
29
|
+
|
30
|
+
MessageBus.publish(
|
31
|
+
"/brainstormings/#{brainstorming.slug}",
|
32
|
+
{ message: "#{I18n.t('brainstorming_ideas.model.publish_create')}: #{name}" }
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def publish_update
|
37
|
+
return if Rails.env.test? || Rails.env.cucumber?
|
38
|
+
|
39
|
+
MessageBus.publish(
|
40
|
+
"/brainstormings/#{brainstorming.slug}",
|
41
|
+
{ message: "#{I18n.t('brainstorming_ideas.model.publish_update')}: #{name}" }
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def publish_destroy
|
46
|
+
return if Rails.env.test? || Rails.env.cucumber?
|
47
|
+
|
48
|
+
MessageBus.publish(
|
49
|
+
"/brainstormings/#{brainstorming.slug}",
|
50
|
+
{ message: "#{I18n.t('brainstorming_ideas.model.publish_destroy')}: #{name}" }
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class BrainstormingIdeaVote < ActiveRecord::Base
|
2
|
+
belongs_to :idea, class_name: 'BrainstormingIdea', counter_cache: 'votes_count'
|
3
|
+
belongs_to :user
|
4
|
+
|
5
|
+
validates :idea_id, presence: true
|
6
|
+
validates :user_id, presence: true, uniqueness: { scope: :idea_id }
|
7
|
+
|
8
|
+
attr_accessible :idea_id
|
9
|
+
|
10
|
+
after_create :publish_create
|
11
|
+
after_destroy :publish_destroy
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def publish_create
|
16
|
+
return if Rails.env.test? || Rails.env.cucumber?
|
17
|
+
|
18
|
+
MessageBus.publish(
|
19
|
+
"/brainstormings/#{idea.brainstorming.slug}",
|
20
|
+
{ message: "#{I18n.t('brainstorming_idea_votes.model.publish_create')}: +1 #{idea.name} by #{user.name}" }
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def publish_destroy
|
25
|
+
return if Rails.env.test? || Rails.env.cucumber?
|
26
|
+
|
27
|
+
MessageBus.publish(
|
28
|
+
"/brainstormings/#{idea.brainstorming.slug}",
|
29
|
+
{ message: "#{I18n.t('brainstorming_idea_votes.model.publish_destroy')}: -1 #{idea.name} by #{user.name}" }
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class BrainstormingIdeaSerializer < ActiveModel::Serializer
|
2
|
+
attributes :id, :user_id, :user_slug, :user_name, :name, :text, :arguments, :votes_count
|
3
|
+
|
4
|
+
def user_slug
|
5
|
+
object.user.try(:slug)
|
6
|
+
end
|
7
|
+
|
8
|
+
def user_name
|
9
|
+
object.user.try(:name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def arguments
|
13
|
+
object.arguments.map{|a| ArgumentSerializer.new(a)}
|
14
|
+
end
|
15
|
+
end
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
en:
|
2
|
+
brainstormings:
|
3
|
+
index:
|
4
|
+
title: Brainstormings
|
5
|
+
your: Your brainstormings
|
6
|
+
empty_collection: No brainstormings found.
|
7
|
+
new:
|
8
|
+
title: New Brainstorming
|
9
|
+
edit:
|
10
|
+
title: Edit Brainstorming
|
11
|
+
save:
|
12
|
+
failed: Something went wrong at saving brainstorming
|
13
|
+
successful: Successfully saved brainstorming.
|
14
|
+
|
15
|
+
create:
|
16
|
+
title: Create Brainstorming
|
17
|
+
update:
|
18
|
+
title: Update Brainstorming
|
19
|
+
|
20
|
+
activerecord:
|
21
|
+
errors:
|
22
|
+
models:
|
23
|
+
brainstorming:
|
24
|
+
attributes:
|
25
|
+
base:
|
26
|
+
deletion_failed: Brainstorming could not be deleted!
|
@@ -0,0 +1,18 @@
|
|
1
|
+
en:
|
2
|
+
brainstorming_idea_votes:
|
3
|
+
create:
|
4
|
+
failed: Something went wrong at creating vote
|
5
|
+
successfully: Successfully voted idea.
|
6
|
+
destroy:
|
7
|
+
successful: Successfully removed vote.
|
8
|
+
model:
|
9
|
+
publish_create: A vote for an idea has been created
|
10
|
+
publish_destroy: A vote for an idea has been removed
|
11
|
+
|
12
|
+
activerecord:
|
13
|
+
errors:
|
14
|
+
models:
|
15
|
+
brainstorming_idea_vote:
|
16
|
+
attributes:
|
17
|
+
base:
|
18
|
+
deletion_failed: Vote could not be removed!
|
@@ -0,0 +1,31 @@
|
|
1
|
+
en:
|
2
|
+
brainstorming_ideas:
|
3
|
+
index:
|
4
|
+
empty_collection: No ideas found.
|
5
|
+
new:
|
6
|
+
title: New Idea
|
7
|
+
save:
|
8
|
+
failed: Something went wrong at saving idea
|
9
|
+
successful: Successfully saved idea.
|
10
|
+
create:
|
11
|
+
title: Create Idea
|
12
|
+
update:
|
13
|
+
title: Update Idea
|
14
|
+
destroy:
|
15
|
+
failed: Removing idea failed!
|
16
|
+
model:
|
17
|
+
publish_create: A new idea has been added
|
18
|
+
publish_update: An idea has been updated
|
19
|
+
publish_destroy: An idea has been removed
|
20
|
+
|
21
|
+
activerecord:
|
22
|
+
errors:
|
23
|
+
models:
|
24
|
+
brainstorming_idea:
|
25
|
+
attributes:
|
26
|
+
base:
|
27
|
+
deletion_failed: Brainstorming idea could not be deleted!
|
28
|
+
|
29
|
+
models:
|
30
|
+
brainstorming_idea: Brainstorming Idea
|
31
|
+
brainstorming_idea_short: Idea
|
data/config/routes.rb
CHANGED
@@ -1,2 +1,11 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
|
+
get '/products/brainstorming' => 'product/brainstorming#index'
|
3
|
+
|
4
|
+
namespace :voluntary, path: 'api', module: 'voluntary/api', defaults: {format: 'json'} do
|
5
|
+
namespace :v1 do
|
6
|
+
resources :brainstormings, only: [:index, :create, :show, :update, :destroy]
|
7
|
+
resources :brainstorming_ideas, only: [:index, :create, :update, :destroy]
|
8
|
+
resources :brainstorming_idea_votes, only: [:index, :create, :destroy]
|
9
|
+
end
|
10
|
+
end
|
2
11
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class AddBrainstormingProduct < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
if Product::Brainstorming.first
|
4
|
+
else
|
5
|
+
Product::Brainstorming.create(name: 'Brainstorming', text: 'Dummy')
|
6
|
+
end
|
7
|
+
|
8
|
+
create_table :brainstormings, force: true do |t|
|
9
|
+
t.integer :user_id
|
10
|
+
t.string :name
|
11
|
+
t.string :slug
|
12
|
+
t.text :text
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :brainstormings, :user_id
|
17
|
+
add_index :brainstormings, [:slug, :user_id], unique: true
|
18
|
+
|
19
|
+
create_table :brainstorming_ideas, force: true do |t|
|
20
|
+
t.integer :brainstorming_id
|
21
|
+
t.integer :user_id
|
22
|
+
t.string :name
|
23
|
+
t.text :text
|
24
|
+
t.integer :votes_count, default: 0
|
25
|
+
t.timestamps
|
26
|
+
end
|
27
|
+
|
28
|
+
add_index :brainstorming_ideas, :user_id
|
29
|
+
add_index :brainstorming_ideas, [:brainstorming_id, :name], unique: true
|
30
|
+
|
31
|
+
create_table :brainstorming_idea_votes, force: true do |t|
|
32
|
+
t.integer :idea_id
|
33
|
+
t.integer :user_id
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
|
37
|
+
add_index :brainstorming_idea_votes, :idea_id
|
38
|
+
add_index :brainstorming_idea_votes, :user_id
|
39
|
+
add_index :brainstorming_idea_votes, [:idea_id, :user_id], unique: true
|
40
|
+
end
|
41
|
+
|
42
|
+
def down
|
43
|
+
if product = Product::Brainstorming.first
|
44
|
+
product.destroy
|
45
|
+
end
|
46
|
+
|
47
|
+
drop_table :brainstormings
|
48
|
+
drop_table :brainstorming_ideas
|
49
|
+
drop_table :brainstorming_idea_votes
|
50
|
+
end
|
51
|
+
end
|
data/lib/voluntary_brainstorming/concerns/model/argument/publishes_changes_to_brainstorming.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module VoluntaryBrainstorming
|
2
|
+
module Concerns
|
3
|
+
module Model
|
4
|
+
module Argument
|
5
|
+
module PublishesChangesToBrainstorming
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
after_create :publish_create_to_brainstorming
|
10
|
+
after_update :publish_update_to_brainstorming
|
11
|
+
before_destroy :publish_destroy_to_brainstorming
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def publish_create_to_brainstorming
|
16
|
+
return if Rails.env.test? || Rails.env.cucumber?
|
17
|
+
return unless argumentable_type == 'BrainstormingIdea'
|
18
|
+
|
19
|
+
MessageBus.publish(
|
20
|
+
"/brainstormings/#{argumentable.brainstorming.slug}",
|
21
|
+
{ message: "#{I18n.t('arguments.model.publish_create_to_brainstorming')}: #{topic.name}" }
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def publish_update_to_brainstorming
|
26
|
+
return if Rails.env.test? || Rails.env.cucumber?
|
27
|
+
return unless argumentable_type == 'BrainstormingIdea'
|
28
|
+
|
29
|
+
MessageBus.publish(
|
30
|
+
"/brainstormings/#{argumentable.brainstorming.slug}",
|
31
|
+
{ message: "#{I18n.t('arguments.model.publish_update_to_brainstorming')}: #{topic.name}" }
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def publish_destroy_to_brainstorming
|
36
|
+
return if Rails.env.test? || Rails.env.cucumber?
|
37
|
+
return unless argumentable_type == 'BrainstormingIdea'
|
38
|
+
|
39
|
+
MessageBus.publish(
|
40
|
+
"/brainstormings/#{argumentable.brainstorming.slug}",
|
41
|
+
{ message: "#{I18n.t('arguments.model.publish_destroy_to_brainstorming')}: #{topic.name}" }
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module VoluntaryBrainstorming
|
2
|
+
module Concerns
|
3
|
+
module Model
|
4
|
+
module User
|
5
|
+
module HasBrainstormings
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
has_many :brainstormings
|
10
|
+
has_many :brainstorming_ideas
|
11
|
+
has_many :brainstorming_idea_votes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|