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.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +3 -2
  3. data/app/assets/javascripts/voluntary_brainstorming/app.js.coffee +8 -0
  4. data/app/assets/javascripts/voluntary_brainstorming/application.js +4 -0
  5. data/app/assets/javascripts/voluntary_brainstorming/components/brainstorming_idea_argument_component.js.coffee +63 -0
  6. data/app/assets/javascripts/voluntary_brainstorming/components/brainstorming_idea_cell_component.js.coffee +34 -0
  7. data/app/assets/javascripts/voluntary_brainstorming/components/brainstorming_idea_vote_component.js.coffee +46 -0
  8. data/app/assets/javascripts/voluntary_brainstorming/controllers/brainstorming_controller.js.coffee +79 -0
  9. data/app/assets/javascripts/voluntary_brainstorming/controllers/user_brainstormings_controller.js.coffee +5 -0
  10. data/app/assets/javascripts/voluntary_brainstorming/mixins/destroy_brainstorming.js.coffee +14 -0
  11. data/app/assets/javascripts/voluntary_brainstorming/mixins/pagination_controller.js.coffee +43 -0
  12. data/app/assets/javascripts/voluntary_brainstorming/models/brainstorming.js.coffee +6 -0
  13. data/app/assets/javascripts/voluntary_brainstorming/models/user.js.coffee +18 -0
  14. data/app/assets/javascripts/voluntary_brainstorming/router.js.coffee +9 -0
  15. data/app/assets/javascripts/voluntary_brainstorming/routes/brainstorming_route.js.coffee +37 -0
  16. data/app/assets/javascripts/voluntary_brainstorming/routes/edit_brainstorming_route.js.coffee +16 -0
  17. data/app/assets/javascripts/voluntary_brainstorming/routes/index_route.js.coffee +4 -0
  18. data/app/assets/javascripts/voluntary_brainstorming/routes/new_brainstorming_route.js.coffee +5 -0
  19. data/app/assets/javascripts/voluntary_brainstorming/routes/user_brainstormings_route.js.coffee +20 -0
  20. data/app/assets/javascripts/voluntary_brainstorming/templates/application.handlebars.erb +20 -0
  21. data/app/assets/javascripts/voluntary_brainstorming/templates/brainstorming.js.handlebars +77 -0
  22. data/app/assets/javascripts/voluntary_brainstorming/templates/brainstorming_form.js.handlebars +18 -0
  23. data/app/assets/javascripts/voluntary_brainstorming/templates/brainstorming_idea_form.js.handlebars +19 -0
  24. data/app/assets/javascripts/voluntary_brainstorming/templates/components/brainstorming-idea-argument.js.handlebars +86 -0
  25. data/app/assets/javascripts/voluntary_brainstorming/templates/components/brainstorming-idea-cell.js.handlebars +7 -0
  26. data/app/assets/javascripts/voluntary_brainstorming/templates/components/brainstorming-idea-vote.js.handlebars +6 -0
  27. data/app/assets/javascripts/voluntary_brainstorming/templates/edit_brainstorming.js.handlebars +3 -0
  28. data/app/assets/javascripts/voluntary_brainstorming/templates/navigation.js.handlebars +28 -0
  29. data/app/assets/javascripts/voluntary_brainstorming/templates/new_brainstorming.js.handlebars +3 -0
  30. data/app/assets/javascripts/voluntary_brainstorming/templates/shared/_pagination.js.handlebars +23 -0
  31. data/app/assets/javascripts/voluntary_brainstorming/templates/user_brainstormings.js.handlebars +33 -0
  32. data/app/assets/stylesheets/voluntary_brainstorming/application.css +13 -0
  33. data/app/controllers/product/brainstorming_controller.rb +16 -0
  34. data/app/controllers/voluntary/api/v1/brainstorming_idea_votes_controller.rb +38 -0
  35. data/app/controllers/voluntary/api/v1/brainstorming_ideas_controller.rb +66 -0
  36. data/app/controllers/voluntary/api/v1/brainstormings_controller.rb +70 -0
  37. data/app/models/brainstorming.rb +18 -0
  38. data/app/models/brainstorming_idea.rb +53 -0
  39. data/app/models/brainstorming_idea_vote.rb +32 -0
  40. data/app/models/product/brainstorming.rb +2 -0
  41. data/app/serializers/brainstorming_idea_serializer.rb +15 -0
  42. data/app/serializers/brainstorming_idea_vote_serializer.rb +11 -0
  43. data/app/serializers/brainstorming_serializer.rb +7 -0
  44. data/app/views/product/brainstorming/index.html.erb +0 -0
  45. data/config/locales/resources/brainstorming/en.yml +26 -0
  46. data/config/locales/resources/brainstorming_idea_votes/en.yml +18 -0
  47. data/config/locales/resources/brainstorming_ideas/en.yml +31 -0
  48. data/config/routes.rb +9 -0
  49. data/db/migrate/20150818181847_add_brainstorming_product.rb +51 -0
  50. data/lib/voluntary_brainstorming.rb +5 -1
  51. data/lib/voluntary_brainstorming/concerns/model/argument/publishes_changes_to_brainstorming.rb +49 -0
  52. data/lib/voluntary_brainstorming/concerns/model/user/has_brainstormings.rb +17 -0
  53. data/lib/voluntary_brainstorming/engine.rb +13 -0
  54. data/lib/voluntary_brainstorming/version.rb +1 -1
  55. metadata +322 -37
  56. 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,2 @@
1
+ class Product::Brainstorming < ::Product
2
+ 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
@@ -0,0 +1,11 @@
1
+ class BrainstormingIdeaVoteSerializer < ActiveModel::Serializer
2
+ attributes :id, :idea_id, :user_id, :user_slug, :user_name
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
+ end
@@ -0,0 +1,7 @@
1
+ class BrainstormingSerializer < ActiveModel::Serializer
2
+ attributes :id, :user_id, :user_slug, :name, :slug, :text
3
+
4
+ def user_slug
5
+ object.user.try(:slug)
6
+ end
7
+ end
@@ -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
@@ -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
@@ -1,4 +1,8 @@
1
- require "voluntary_brainstorming/engine"
1
+ require 'voluntary'
2
+
3
+ require 'message_bus'
4
+
5
+ require 'voluntary_brainstorming/engine'
2
6
 
3
7
  module VoluntaryBrainstorming
4
8
  end
@@ -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