summaryrefslogtreecommitdiff
path: root/lib/aggiedit
diff options
context:
space:
mode:
Diffstat (limited to 'lib/aggiedit')
-rw-r--r--lib/aggiedit/accounts/user.ex2
-rw-r--r--lib/aggiedit/roles.ex2
-rw-r--r--lib/aggiedit/rooms.ex21
-rw-r--r--lib/aggiedit/rooms/comment.ex20
-rw-r--r--lib/aggiedit/rooms/post.ex6
-rw-r--r--lib/aggiedit/rooms/vote.ex20
6 files changed, 68 insertions, 3 deletions
diff --git a/lib/aggiedit/accounts/user.ex b/lib/aggiedit/accounts/user.ex
index 65c2463..45c6525 100644
--- a/lib/aggiedit/accounts/user.ex
+++ b/lib/aggiedit/accounts/user.ex
@@ -14,6 +14,8 @@ defmodule Aggiedit.Accounts.User do
belongs_to :room, Room, on_replace: :update
has_many :posts, Aggiedit.Rooms.Post
+ has_many :votes, Aggiedit.Post.Vote
+ has_many :comments, Aggiedit.Post.Comment
timestamps()
end
diff --git a/lib/aggiedit/roles.ex b/lib/aggiedit/roles.ex
index 3ec6bfd..41da54a 100644
--- a/lib/aggiedit/roles.ex
+++ b/lib/aggiedit/roles.ex
@@ -6,7 +6,7 @@ defmodule Aggiedit.Roles do
def guard?(user, action, object)
def guard?(%User{role: :admin}, _, _), do: true
def guard?(%User{room_id: rid}, :index, %Room{id: rid}), do: true
- def guard?(%User{room_id: rid}, :show, %Post{room_id: rid}), do: true
+ def guard?(%User{room_id: rid}, action, %Post{room_id: rid}) when action in [:show, :vote], do: true
def guard?(%User{id: id, room_id: rid}, action, %Post{user_id: id, room_id: rid}) when action in [:delete, :edit], do: true
def guard?(_, _, _), do: false
diff --git a/lib/aggiedit/rooms.ex b/lib/aggiedit/rooms.ex
index 898dfe1..41df588 100644
--- a/lib/aggiedit/rooms.ex
+++ b/lib/aggiedit/rooms.ex
@@ -6,9 +6,11 @@ defmodule Aggiedit.Rooms do
import Ecto.Query, warn: false
alias Aggiedit.Repo
- alias Aggiedit.Accounts
+ alias Aggiedit.Accounts.User
alias Aggiedit.Rooms.Room
+ alias Aggiedit.Post.{Vote, Comment}
+
alias Phoenix.PubSub
def list_rooms do
@@ -91,6 +93,23 @@ defmodule Aggiedit.Rooms do
Post.changeset(post, attrs)
end
+ def vote_count(post) do
+ votes = post
+ |> Repo.preload(:votes)
+ |> Map.get(:votes)
+ |> Enum.map(fn vote -> if vote.is_up, do: 1, else: -1 end)
+ |> Enum.sum()
+ end
+
+ def vote_post(%Post{} = post, %User{} = user, direction) do
+ is_up = direction == "upvote"
+ vote = %Vote{is_up: is_up, user: user, post: post}
+ |> Repo.insert(on_conflict: [set: [is_up: is_up]], conflict_target: [:user_id, :post_id])
+ post = change_post(post, %{score: vote_count(post)})
+ |> Repo.update()
+ broadcast_post_over_room(post, :post_voted)
+ end
+
defp broadcast_post_over_room({:error, _reason}=error, _event), do: error
defp broadcast_post_over_room({:ok, post}, event) do
PubSub.broadcast(Aggiedit.PubSub, "room:#{post.room_id}:posts", {event, post})
diff --git a/lib/aggiedit/rooms/comment.ex b/lib/aggiedit/rooms/comment.ex
new file mode 100644
index 0000000..6747ba3
--- /dev/null
+++ b/lib/aggiedit/rooms/comment.ex
@@ -0,0 +1,20 @@
+defmodule Aggiedit.Post.Comment do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ schema "post_comments" do
+ field :comment, :string
+
+ belongs_to :user, Aggiedit.Accounts.User
+ belongs_to :post, Aggiedit.Rooms.Post
+
+ timestamps()
+ end
+
+ @doc false
+ def changeset(comment, attrs) do
+ comment
+ |> cast(attrs, [:comment])
+ |> validate_required([:comment])
+ end
+end
diff --git a/lib/aggiedit/rooms/post.ex b/lib/aggiedit/rooms/post.ex
index ee9450d..e1aa59a 100644
--- a/lib/aggiedit/rooms/post.ex
+++ b/lib/aggiedit/rooms/post.ex
@@ -5,18 +5,22 @@ defmodule Aggiedit.Rooms.Post do
schema "posts" do
field :body, :string
field :title, :string
+ field :score, :integer
belongs_to :room, Aggiedit.Rooms.Room
belongs_to :user, Aggiedit.Accounts.User
belongs_to :upload, Aggiedit.Uploads.Upload
+ has_many :votes, Aggiedit.Post.Vote
+ has_many :comments, Aggiedit.Post.Comment
+
timestamps()
end
@doc false
def changeset(post, attrs) do
post
- |> cast(attrs, [:title, :body])
+ |> cast(attrs, [:title, :body, :score])
|> validate_required([:title, :body])
end
diff --git a/lib/aggiedit/rooms/vote.ex b/lib/aggiedit/rooms/vote.ex
new file mode 100644
index 0000000..f402e87
--- /dev/null
+++ b/lib/aggiedit/rooms/vote.ex
@@ -0,0 +1,20 @@
+defmodule Aggiedit.Post.Vote do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ schema "post_votes" do
+ field :is_up, :boolean
+
+ belongs_to :user, Aggiedit.Accounts.User
+ belongs_to :post, Aggiedit.Rooms.Post
+
+ timestamps()
+ end
+
+ @doc false
+ def changeset(vote, attrs) do
+ vote
+ |> cast(attrs, [:direction])
+ |> validate_required([:direction])
+ end
+end