feat(controllers): add AccountController, edit and ApplicationController
This commit is contained in:
1 parent
550ce1dbce
commit
89fb0a8d43
2 files changed
+180
No files matched your search
@@ -0,0 +1,68 @@
|
||||
class AccountController < ApplicationController
|
||||
before_action :require_authentication
|
||||
|
||||
def edit
|
||||
render(:edit, locals: { user: current_user, errors: [] })
|
||||
end
|
||||
|
||||
# current_user.comments is a plain `Comment.where(user_id: id)` (Associable
|
||||
# #has_many, no through:/as:) - a single HashNode equality answerable by
|
||||
# Store#lookup_by_index on comments.user_id the moment that index exists
|
||||
# (see db/migrate/20260907000008_add_index_on_comments_user_id.rb), unlike
|
||||
# every other approved/visible_to call site in this app: those all chain
|
||||
# off post.comments first, so their equalities hash already carries
|
||||
# post_id too and the pre-existing post_id index wins the tie - this is
|
||||
# the one place comments.user_id gets to be the index actually picked.
|
||||
def comments
|
||||
comments = current_user.comments.order(:created_at, :desc).page(params['page']).per(10)
|
||||
fresh_when(etag: [current_user.id, comments.current_page, comments.total_count,
|
||||
comments.to_a.map { |c| [c.id, c.updated_at] }])
|
||||
render(:comments, locals: { comments: comments })
|
||||
end
|
||||
|
||||
# A post's comments start life pending (Comment's `enum :status`) so its
|
||||
# author can approve/reject before strangers see them - but the only way
|
||||
# to act on that today is opening each post's own page one at a time
|
||||
# (posts/_comment.erb's approve/reject buttons). This gathers every
|
||||
# pending comment across EVERY post the current user owns onto one page,
|
||||
# the same "flatten across posts" shape as #comments above but filtered
|
||||
# to pending instead of to authorship. Two index-backed queries, not one
|
||||
# scan each: current_user.posts (posts.user_id, see the migration
|
||||
# referenced on User) narrows to this user's own post ids first, then
|
||||
# Comment.pending.where(post_id: ...) reuses the existing comments.post_id
|
||||
# index's IN-list lookup (Store#lookup_by_index_in) across all of them at
|
||||
# once, with the leftover `status` equality filtered from that already-
|
||||
# small candidate set in memory - see ConditionNode#indexed_candidates.
|
||||
def moderation
|
||||
post_ids = current_user.posts.pluck(:id)
|
||||
comments = Comment.pending.where(post_id: post_ids)
|
||||
.order(:created_at, :desc).page(params['page']).per(10)
|
||||
fresh_when(etag: [current_user.id, comments.current_page, comments.total_count,
|
||||
comments.to_a.map { |c| [c.id, c.updated_at] }])
|
||||
render(:moderation, locals: { comments: comments })
|
||||
end
|
||||
|
||||
# User#email is `encrypts :email, deterministic: true` (see the model) -
|
||||
# this is the one place in the whole demo where a user's own encrypted
|
||||
# attribute is genuinely rewritten through a real HTTP request instead of
|
||||
# only being set once at sign-up, which is exactly what forces a fresh
|
||||
# `Encryption.encrypt` call under the CURRENTLY configured primary key.
|
||||
# That makes this action the natural vehicle for exercising key rotation
|
||||
# end to end (see rotation_worker.rb): a user who visits this page after
|
||||
# the app's encryption secret has rotated and re-saves their (possibly
|
||||
# unchanged) email migrates that one row onto the new key for free,
|
||||
# exactly the way Prism::Orm::Encryption's own comments describe.
|
||||
def update
|
||||
attrs = params.require('user').permit(:email).to_h
|
||||
current_user.assign(attrs)
|
||||
|
||||
if current_user.save
|
||||
changed_fields = current_user.saved_changes.keys - ['updated_at']
|
||||
flash[:notice] = changed_fields.empty? ? t('account.update_noop_notice') : t('account.updated_notice', fields: changed_fields.join(', '))
|
||||
redirect url_for(:edit_account)
|
||||
else
|
||||
status(422)
|
||||
render(:edit, locals: { user: current_user, errors: current_user.errors.full_messages })
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user