diff --git a/priv/repo/migrations/20170815184450_add_vote_table.exs b/priv/repo/migrations/20170815184450_add_vote_table.exs
new file mode 100644
index 000000000..060f42f00
--- /dev/null
+++ b/priv/repo/migrations/20170815184450_add_vote_table.exs
@@ -0,0 +1,18 @@
+defmodule RemoteRetro.Repo.Migrations.AddVoteTable do
+ use Ecto.Migration
+
+ def change do
+ create table(:votes) do
+ add :user_id, references(:users, [
+ column: :id,
+ on_delete: :nothing
+ ])
+ add :idea_id, references(:ideas, [
+ column: :id,
+ on_delete: :nothing
+ ])
+
+ timestamps()
+ end
+ end
+end
diff --git a/web/channels/retro_channel.ex b/web/channels/retro_channel.ex
index 6e655beda..5f33a8e00 100644
--- a/web/channels/retro_channel.ex
+++ b/web/channels/retro_channel.ex
@@ -1,7 +1,7 @@
defmodule RemoteRetro.RetroChannel do
use RemoteRetro.Web, :channel
- alias RemoteRetro.{Presence, PresenceUtils, Idea, Emails, Mailer, Retro}
+ alias RemoteRetro.{Presence, PresenceUtils, Idea, Emails, Mailer, Retro, Vote}
def join("retro:" <> retro_id, _, socket) do
socket = assign(socket, :retro_id, retro_id)
@@ -76,11 +76,16 @@ defmodule RemoteRetro.RetroChannel do
{:noreply, socket}
end
- def handle_in("submit_vote", %{"id" => id}, socket) do
- query = from i in Idea, where: i.id == ^id
- {_row_count, [updated_idea]} = Repo.update_all(query, [inc: [vote_count: 1]], returning: true)
+ def handle_in("submit_vote", %{"ideaId" => idea_id, "userId" => user_id}, socket) do
+ vote =
+ %Vote{
+ idea_id: idea_id,
+ user_id: user_id
+ }
+ |> Vote.changeset
+ |> Repo.insert!
- broadcast! socket, "vote_submitted", updated_idea
+ broadcast! socket, "vote_submitted", vote
{:noreply, socket}
end
diff --git a/web/models/idea.ex b/web/models/idea.ex
index 57455ace2..327297892 100644
--- a/web/models/idea.ex
+++ b/web/models/idea.ex
@@ -9,6 +9,7 @@ defmodule RemoteRetro.Idea do
belongs_to :retro, RemoteRetro.Retro, type: Ecto.UUID
belongs_to :user, RemoteRetro.User
+ has_many :vote, RemoteRetro.Vote
timestamps(type: :utc_datetime)
end
diff --git a/web/models/user.ex b/web/models/user.ex
index 4d1d1d5a7..6d0fbd795 100644
--- a/web/models/user.ex
+++ b/web/models/user.ex
@@ -25,6 +25,7 @@ defmodule RemoteRetro.User do
field :last_login, Ecto.DateTime
has_many :participations, RemoteRetro.Participation
+ has_many :votes, RemoteRetro.Vote
timestamps(type: :utc_datetime)
end
diff --git a/web/models/vote.ex b/web/models/vote.ex
new file mode 100644
index 000000000..9d9890e15
--- /dev/null
+++ b/web/models/vote.ex
@@ -0,0 +1,19 @@
+defmodule RemoteRetro.Vote do
+ use RemoteRetro.Web, :model
+
+ @derive {Poison.Encoder, except: [:__meta__]}
+ schema "votes" do
+ belongs_to :user, RemoteRetro.User
+ belongs_to :idea, RemoteRetro.Idea
+
+ timestamps(type: :utc_datetime)
+ end
+
+ @required_fields [:user_id, :idea_id]
+
+ def changeset(struct, params \\ %{}) do
+ struct
+ |> cast(params, @required_fields)
+ |> validate_required(@required_fields)
+ end
+end
diff --git a/web/static/js/components/idea_controls.jsx b/web/static/js/components/idea_controls.jsx
index a4e08d70c..c195d93f0 100644
--- a/web/static/js/components/idea_controls.jsx
+++ b/web/static/js/components/idea_controls.jsx
@@ -24,7 +24,11 @@ const IdeaControls = props => {
function renderIcons() {
if (stage !== "idea-generation" && category !== "action-item") {
return (
-
+
)
}
if (currentUser.is_facilitator) {
diff --git a/web/static/js/components/vote_counter.jsx b/web/static/js/components/vote_counter.jsx
index add049014..10f798262 100644
--- a/web/static/js/components/vote_counter.jsx
+++ b/web/static/js/components/vote_counter.jsx
@@ -9,8 +9,8 @@ class VoteCounter extends React.Component {
}
handleClick() {
- const { idea, retroChannel } = this.props
- retroChannel.push("submit_vote", { id: idea.id })
+ const { idea, retroChannel, currentUser } = this.props
+ retroChannel.push("submit_vote", { ideaId: idea.id, userId: currentUser.id })
}
render() {
@@ -32,6 +32,7 @@ class VoteCounter extends React.Component {
VoteCounter.propTypes = {
retroChannel: AppPropTypes.retroChannel.isRequired,
idea: AppPropTypes.idea.isRequired,
+ currentUser: AppPropTypes.user.isRequired,
}
export default VoteCounter
diff --git a/web/static/js/reducers/ideas.js b/web/static/js/reducers/ideas.js
index 20a6de6f7..2d4eb07a4 100644
--- a/web/static/js/reducers/ideas.js
+++ b/web/static/js/reducers/ideas.js
@@ -1,3 +1,5 @@
+// const updateIdea = state
+
const ideas = (state = [], action) => {
switch (action.type) {
case "SET_INITIAL_STATE":
diff --git a/web/static/js/services/retro_channel.js b/web/static/js/services/retro_channel.js
index 358732d87..54b19b732 100644
--- a/web/static/js/services/retro_channel.js
+++ b/web/static/js/services/retro_channel.js
@@ -47,8 +47,9 @@ const applyListenerCallbacks = (retroChannel, store, actions) => {
actions.deleteIdea(deletedIdea.id)
})
- retroChannel.on("vote_submitted", votedOnIdea => {
- actions.updateIdea(votedOnIdea.id, { vote_count: votedOnIdea.vote_count })
+ retroChannel.on("vote_submitted", ideaId => {
+ // actions.updateIdea(votedOnIdea.id, { vote_count: votedOnIdea.vote_count })
+ console.log("in vote submitted", ideaId)
})
retroChannel.on("idea_highlighted", highlightedIdea => {