New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add messages #1278
Add messages #1278
Conversation
field :subject, :string | ||
|
||
belongs_to :author, CodeCorps.User | ||
belongs_to :project, CodeCorps.Project |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm understanding this correctly, this has no recipient yet? That goes into Conversation
? The author is the user starting the message, the project is the project the user is a member/admin of.
If this is correct, or if it not correct and I'm misunderstanding it completely, I'm thinking it should be part of the
moduledoc
either way, since it's not completely intuitive (albeit for good reasons).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The author
is not necessarily a member of the project. The message could be to the project without the author
being a member.
lib/code_corps/model/message.ex
Outdated
defp do_maybe_validate_subject(changeset, "admin") do | ||
changeset |> validate_required(:subject) | ||
end | ||
defp do_maybe_validate_subject(changeset, _), do: changeset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just call this chain require_subject_if_admin
. Makes it clearer and foregoes the need for a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to tie it to the admin specifically in the method signature, but probably fine for now to do that.
lib/code_corps/policy/message.ex
Outdated
|
||
def create?(%User{id: id}, %{"initiated_by" => "user", "author_id" => author_id}) do | ||
id == author_id | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a guard clause would work better here
def create?(%User{id: id}, %{"initiated_by" => "user", "author_id" => author_id})
when id == author_id, do: true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only because the fallback is false. I'll make the change, but I'm not sure if I understand the argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a guard may be faster (not sure if it actually is here) and, additionally, stresses that there are no side effects to the check since only kernel functions can be used in guards.
It seems arbitrary, and probably doesn't affect much, if anything here, but generally it's preferred to avoid entering the function at all if it's easy to do, which it is here.
88b9405
to
080c1a0
Compare
@joshsmith I've moved the list subclause logic into a separate
|
d5b6243
to
c23e531
Compare
@joshsmith I couldn't find an authorization approach for index that wouldn't completely kill our performance, so instead, I pushed up a commit which offers an alternative - With this, our index route would not return a 403 and instead just return the data the user is authorized to view. That would mean anything ranging from no data, to some data, to all the data in the case of admin users. The idea is that we apply the scope first, then apply the filters, although technically, any order would work. Looking at authorization libraries, scopes are a common solution to the problem of index authorization. For endpoints where we discriminate purely on user type (admin or not admin) returning a 403 would still be an option, but I really don't think returning a 403 when only some of the results are inaccessible is intuitive, nor is it manageable performance-wise. However, if you disagree, I tried to write this without affecting the rest of the PR, so it can be reversible. Even |
19c4ee3
to
e48fe83
Compare
To make my previous commit stick, what we need to do is
|
While working on this, I found a bug, or at the very least, an inconsistency we need to deal with. I created an issue for it in #1282 |
@joshsmith You're the author, so I can't request your review, but this checks all the boxes in the PR description, so it should be good to review/merge |
@joshsmith Due to findings from other issues I've created, it may be that
That means good chunks of this PR will get removed. However, I would still like to get it merged, since it's possible to reappropriate most of the code for reuse in issues linked above - #1286, #1287, #1288, #1289, #1290, #1291, #1292 I've created #1294 and #1293 to deal with remaining problems once this is merged |
@joshsmith @begedin This looks great! So a conversation has many messages? Is the reason to move the index route to a Conversation due to the desire to create threads? If so, what role does Messages play in the UI? Trying to draw out a map of Conversations and Messages and how it is painted in the UI. |
@snewcomer Actually, it's the other way around. A project admin could send out a message to multiple users. That would create a single message, belonging to the project and authored by the admin, as well as multiple conversations - one for each user. Once replies to a conversation start going in, conversation parts get created. That means you can run separate conversations with different users from one starting message. On the other side, a user could also message a project. This would create a Message authored by that user, belonging to that project, as well as a single Conversation belonging to that user and that message. Once replies start going in, it works pretty much the same as above. As I said in my previous comment, this PR is sort of wrong, and needs to be corrected post merge, but the work done here is useful for solving other problems, so we want to get it in. |
I think we do need an |
@joshsmith As I said, we might need it anyway, which is one of several reasons why I'd prefer to merge this as is, barring any serious oversights, and move on from there. |
I can't review myself but this is good to merge. |
2d5c56e
to
978300d
Compare
What's in this PR?
References
Progress on: #1234