feat(controllers): extend posts_controller with publish and unpublish
This commit is contained in:
1 parent
985e87fb68
commit
2226e46cd6
3 files changed
+155
No files matched your search
@@ -287,4 +287,65 @@ class PostsController < ApplicationController
|
|||||||
flash[:notice] = t('posts.restored_notice', id: post.id)
|
flash[:notice] = t('posts.restored_notice', id: post.id)
|
||||||
redirect url_for(:trash_posts)
|
redirect url_for(:trash_posts)
|
||||||
rescue Prism::Orm::RecordNotFound
|
rescue Prism::Orm::RecordNotFound
|
||||||
|
respond_not_found(t('posts.not_found'))
|
||||||
|
end
|
||||||
|
|
||||||
|
# `published!`/`draft!` come straight from Post's `enum :status` (see the
|
||||||
|
# model) - they set the column and save() in one call, so this action is
|
||||||
|
# nothing but "find, authorize like an edit, flip the status".
|
||||||
|
def publish
|
||||||
|
post = Post.find_by!(slug: params['slug'])
|
||||||
|
authorize(post, :update?)
|
||||||
|
post.published!
|
||||||
|
flash[:notice] = t('posts.published_notice', id: post.id)
|
||||||
|
redirect url_for(:post, slug: post.to_param)
|
||||||
|
rescue Prism::Orm::RecordNotFound
|
||||||
|
respond_not_found(t('posts.not_found'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def unpublish
|
||||||
|
post = Post.find_by!(slug: params['slug'])
|
||||||
|
authorize(post, :update?)
|
||||||
|
post.draft!
|
||||||
|
flash[:notice] = t('posts.unpublished_notice', id: post.id)
|
||||||
|
redirect url_for(:post, slug: post.to_param)
|
||||||
|
rescue Prism::Orm::RecordNotFound
|
||||||
|
respond_not_found(t('posts.not_found'))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Post#acts_as_list is scoped by `featured` (see the model) - moving a
|
||||||
|
# post that ISN'T currently featured is harmless (it just reorders it
|
||||||
|
# inside the unused non-featured group) but pointless, so both actions
|
||||||
|
# redirect back to the SAME featured=1 view the reorder links only ever
|
||||||
|
# appear on, regardless of which group the post actually belongs to.
|
||||||
|
def move_up
|
||||||
|
post = Post.find_by!(slug: params['slug'])
|
||||||
|
authorize(post, :update?)
|
||||||
|
post.move_higher
|
||||||
|
redirect "#{url_for(:posts)}?featured=1"
|
||||||
|
rescue Prism::Orm::RecordNotFound
|
||||||
|
respond_not_found(t('posts.not_found'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def move_down
|
||||||
|
post = Post.find_by!(slug: params['slug'])
|
||||||
|
authorize(post, :update?)
|
||||||
|
post.move_lower
|
||||||
|
redirect "#{url_for(:posts)}?featured=1"
|
||||||
|
rescue Prism::Orm::RecordNotFound
|
||||||
|
respond_not_found(t('posts.not_found'))
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def store_cover(upload)
|
||||||
|
return nil unless upload.is_a?(Prism::UploadedFile)
|
||||||
|
return nil if upload.original_filename.to_s.empty?
|
||||||
|
|
||||||
|
uploads_dir = File.join(APP_ROOT, 'public', 'uploads')
|
||||||
|
FileUtils.mkdir_p(uploads_dir)
|
||||||
|
safe_name = "#{Time.now.strftime('%Y%m%d%H%M%S')}-#{upload.original_filename.gsub(/[^a-zA-Z0-9_.-]/, '_')}"
|
||||||
|
File.binwrite(File.join(uploads_dir, safe_name), upload.read)
|
||||||
|
safe_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
class SessionController < ApplicationController
|
||||||
|
def new
|
||||||
|
render(:new, locals: { errors: [] })
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
credentials = params.require('user').permit(:email, :password, :remember_me).to_h
|
||||||
|
user = User.find_by(email: credentials['email'])
|
||||||
|
|
||||||
|
if user && user.authenticate(credentials['password'])
|
||||||
|
sign_in(user, remember: credentials['remember_me'] == '1')
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
flash[:notice] = t('sessions.signed_in_notice')
|
||||||
|
redirect after_authentication_url
|
||||||
|
end
|
||||||
|
format.json { json(user.as_json(methods: [:email])) }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
status(422)
|
||||||
|
render(:new, locals: { errors: [t('sessions.invalid_credentials')] })
|
||||||
|
end
|
||||||
|
# 401, not 422 like the HTML branch above: there is no resource
|
||||||
|
# here whose validation failed (no User object at all when the
|
||||||
|
# email does not match anyone), just a rejected authentication
|
||||||
|
# attempt - the JSON:API status a client should actually branch on.
|
||||||
|
format.json do
|
||||||
|
json({ errors: [jsonapi_error(status: 401, pointer: '/data/attributes/password',
|
||||||
|
title: 'invalid credentials', detail: t('sessions.invalid_credentials'))] }, 401)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
sign_out
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
flash[:notice] = t('sessions.signed_out_notice')
|
||||||
|
redirect url_for(:root)
|
||||||
|
end
|
||||||
|
format.json { json({ message: t('sessions.signed_out_notice') }) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
class UsersController < ApplicationController
|
||||||
|
def new
|
||||||
|
render(:new, locals: { user: User.new, errors: [] })
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
attrs = params.require('user').permit(:email, :password, :password_confirmation).to_h
|
||||||
|
user = User.new(attrs)
|
||||||
|
|
||||||
|
if user.save
|
||||||
|
sign_in(user)
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
flash[:notice] = t('users.signed_up_notice')
|
||||||
|
redirect url_for(:root)
|
||||||
|
end
|
||||||
|
format.json { json(user.as_json(methods: [:email]), 201) }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
status(422)
|
||||||
|
render(:new, locals: { user: user, errors: user.errors.full_messages })
|
||||||
|
end
|
||||||
|
format.json { render_errors(user) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# The unique index on users.email (see db/migrate) is a storage-level
|
||||||
|
# constraint, not just the app-level `validates :email, uniqueness: true`
|
||||||
|
# above - it still fires for anything that reaches Store#insert without
|
||||||
|
# going through Model#valid? first (a racing concurrent signup that read
|
||||||
|
# the table before the other one committed, a future admin script, a bug
|
||||||
|
# elsewhere that skips validation). #create can't tell those apart from a
|
||||||
|
# normal duplicate, so it reports the same friendly message either way.
|
||||||
|
rescue Prism::Orm::Store::UniqueConstraintViolation
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
status(422)
|
||||||
|
render(:new, locals: { user: user, errors: [t('users.email_taken_notice')] })
|
||||||
|
end
|
||||||
|
format.json do
|
||||||
|
json({ errors: [jsonapi_error(status: 422, pointer: '/data/attributes/email',
|
||||||
|
title: 'is taken', detail: t('users.email_taken_notice'))] }, 422)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in new issue
Block a user