actualizar y eliminar artículos
This commit is contained in:
parent
1c96e0b0ff
commit
da77ecf43f
11 changed files with 107 additions and 69 deletions
|
@ -58,29 +58,17 @@ class PostsController < ApplicationController
|
|||
|
||||
def update
|
||||
@site = find_site
|
||||
@lang = find_lang(@site)
|
||||
@post = find_post(@site)
|
||||
@post = @site.posts.find params[:id]
|
||||
|
||||
authorize @post
|
||||
|
||||
@post.update_attributes(repair_nested_params(post_params))
|
||||
service = PostService.new(site: @site,
|
||||
post: @post,
|
||||
usuarie: current_usuarie,
|
||||
params: params)
|
||||
|
||||
# Solo las usuarias pueden modificar la autoría
|
||||
if @site.usuarie? current_usuarie
|
||||
if params[:post][:author].present?
|
||||
@post.update_attributes(author: params[:post][:author])
|
||||
end
|
||||
@post.update_attributes(draft: false)
|
||||
else
|
||||
# Todo lo que crean les invitades es borrador
|
||||
@post.update_attributes(draft: true)
|
||||
end
|
||||
|
||||
if @post.save
|
||||
flash[:success] = @site.config.dig('thanks')
|
||||
redirect_to site_posts_path(@site,
|
||||
category: session[:category],
|
||||
lang: @lang)
|
||||
if service.update.persisted?
|
||||
redirect_to site_posts_path(@site)
|
||||
else
|
||||
render 'posts/edit'
|
||||
end
|
||||
|
@ -89,14 +77,17 @@ class PostsController < ApplicationController
|
|||
# Eliminar artículos
|
||||
def destroy
|
||||
@site = find_site
|
||||
@lang = find_lang(@site)
|
||||
@post = find_post(@site)
|
||||
@post = @site.posts.find params[:id]
|
||||
|
||||
authorize @post
|
||||
|
||||
@post.destroy
|
||||
service = PostService.new(site: @site,
|
||||
post: @post,
|
||||
usuarie: current_usuarie,
|
||||
params: params)
|
||||
|
||||
redirect_to site_posts_path(@site, category: session[:category],
|
||||
lang: @lang)
|
||||
# TODO: Notificar si se pudo o no
|
||||
service.destroy
|
||||
redirect_to site_posts_path(@site)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -136,16 +136,13 @@ class Post < OpenStruct
|
|||
|
||||
# Eliminar el artículo del repositorio y de la lista de artículos del
|
||||
# sitio
|
||||
#
|
||||
# XXX Commit
|
||||
def destroy
|
||||
FileUtils.rm_f path.absolute
|
||||
|
||||
site.posts(lang: lang).delete_if do |post|
|
||||
# TODO: Devolver self en lugar de todo el array
|
||||
site.posts(lang: lang).reject! do |post|
|
||||
post.path.absolute == path.absolute
|
||||
end
|
||||
|
||||
!File.exist?(path.absolute) && !site.posts(lang: lang).include?(self)
|
||||
end
|
||||
alias destroy! destroy
|
||||
|
||||
|
@ -212,6 +209,10 @@ class Post < OpenStruct
|
|||
File.exist?(path.absolute) && full_content == File.read(path.absolute)
|
||||
end
|
||||
|
||||
def destroyed?
|
||||
!File.exist?(path.absolute)
|
||||
end
|
||||
|
||||
def update_attributes(hashable)
|
||||
hashable.to_hash.each do |name, value|
|
||||
self[name].value = value
|
||||
|
|
|
@ -143,7 +143,7 @@ class Site < ApplicationRecord
|
|||
@posts ||= {}
|
||||
lang ||= I18n.locale
|
||||
|
||||
return @posts[lang] if @posts[lang].present?
|
||||
return @posts[lang] if @posts.key? lang
|
||||
|
||||
@posts[lang] = PostRelation.new site: self
|
||||
|
||||
|
|
|
@ -33,12 +33,8 @@ class Site
|
|||
|
||||
# Incorpora los cambios en el repositorio actual
|
||||
#
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def merge(author)
|
||||
master = rugged.branches['master'].target
|
||||
origin = rugged.branches['origin/master'].target
|
||||
merge = rugged.merge_commits(master, origin)
|
||||
def merge(usuarie)
|
||||
merge = rugged.merge_commits(master, origin_master)
|
||||
|
||||
# No hacemos nada si hay conflictos
|
||||
#
|
||||
|
@ -47,23 +43,26 @@ class Site
|
|||
# quién sabe.
|
||||
return if merge.conflicts?
|
||||
|
||||
author = { name: author.name, email: author.email }
|
||||
commit = Rugged::Commit
|
||||
.create(rugged,
|
||||
parents: [master, origin],
|
||||
.create(rugged, update_ref: 'HEAD',
|
||||
parents: [master, origin_master],
|
||||
tree: merge.write_tree(rugged),
|
||||
message: I18n.t('sites.fetch.merge.message'),
|
||||
author: author,
|
||||
committer: author,
|
||||
update_ref: 'HEAD')
|
||||
author: author(usuarie), committer: committer)
|
||||
|
||||
# Forzamos el checkout para mover el HEAD al último commit y
|
||||
# escribir los cambios
|
||||
rugged.checkout 'HEAD', strategy: :force
|
||||
commit
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
def master
|
||||
rugged.branches['master'].target
|
||||
end
|
||||
|
||||
def origin_master
|
||||
rugged.branches['origin/master'].target
|
||||
end
|
||||
|
||||
# Compara los commits entre el repositorio remoto y el actual para
|
||||
# que luego los podamos mostrar.
|
||||
|
@ -86,20 +85,18 @@ class Site
|
|||
end
|
||||
|
||||
# Guarda los cambios en git, de a un archivo por vez
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def commit(file:, usuarie:, message:)
|
||||
rugged.index.add(relativize(file))
|
||||
def commit(file:, usuarie:, message:, remove: false)
|
||||
remove ? rm(file) : add(file)
|
||||
|
||||
# Escribir los cambios para que el repositorio se vea tal cual
|
||||
rugged.index.write
|
||||
|
||||
Rugged::Commit.create(rugged,
|
||||
update_ref: 'HEAD',
|
||||
Rugged::Commit.create(rugged, message: message, update_ref: 'HEAD',
|
||||
parents: [rugged.head.target],
|
||||
tree: rugged.index.write_tree,
|
||||
message: message,
|
||||
author: author(usuarie),
|
||||
committer: committer)
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def author(author)
|
||||
{ name: author.name, email: author.email, time: Time.now }
|
||||
|
@ -109,6 +106,14 @@ class Site
|
|||
{ name: 'Sutty', email: "sutty@#{Site.domain}", time: Time.now }
|
||||
end
|
||||
|
||||
def add(file)
|
||||
rugged.index.add(relativize(file))
|
||||
end
|
||||
|
||||
def rm(file)
|
||||
rugged.index.remove(relativize(file))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def relativize(file)
|
||||
|
|
|
@ -30,11 +30,18 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
|
|||
post
|
||||
end
|
||||
|
||||
def destroy
|
||||
post.destroy! && commit(action: :destroyed)
|
||||
|
||||
post
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def commit(action:)
|
||||
site.repository.commit(file: post.path.absolute,
|
||||
usuarie: usuarie,
|
||||
remove: action == :destroyed,
|
||||
message: I18n.t("post_service.#{action}",
|
||||
title: post.title.value))
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
url = site_posts_path(site)
|
||||
method = :post
|
||||
else
|
||||
url = site_post_path(site, post)
|
||||
url = site_post_path(site, post.id)
|
||||
method = :patch
|
||||
end
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
|||
- type = metadata.type
|
||||
= render "posts/attributes/#{type}",
|
||||
post: post, attribute: attribute,
|
||||
metadata: metadata
|
||||
metadata: metadata, site: site
|
||||
|
||||
-# Botones de guardado
|
||||
= render 'posts/submit', site: site
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
.col
|
||||
= render 'layouts/breadcrumb',
|
||||
crumbs: [link_to(t('sites.index'), sites_path),
|
||||
@site.name,
|
||||
link_to(t('posts.index'),
|
||||
site_posts_path(@site)),
|
||||
link_to(@post.title, site_post_path(@site, @post)),
|
||||
link_to(@site.name, site_posts_path(@site)),
|
||||
link_to(t('posts.index'), site_posts_path(@site)),
|
||||
link_to(@post.title.value, site_post_path(@site, @post.id)),
|
||||
t('posts.edit')]
|
||||
|
||||
.row.justify-content-center
|
||||
.col-md-8
|
||||
= render 'posts/form'
|
||||
= render 'posts/form', site: @site, post: @post
|
||||
|
|
|
@ -6,6 +6,7 @@ en:
|
|||
post_service:
|
||||
created: 'Created "%{title}"'
|
||||
updated: 'Updated "%{title}"'
|
||||
destroyed: 'Removed "%{title}"'
|
||||
metadata:
|
||||
array:
|
||||
cant_be_empty: 'This field cannot be empty'
|
||||
|
|
|
@ -6,6 +6,7 @@ es:
|
|||
post_service:
|
||||
created: 'Creado "%{title}"'
|
||||
updated: 'Modificado "%{title}"'
|
||||
destroyed: 'Eliminado "%{title}"'
|
||||
metadata:
|
||||
array:
|
||||
cant_be_empty: 'El campo no puede estar vacío'
|
||||
|
|
|
@ -93,13 +93,12 @@ Al instanciar un `Post`, se pasan el sitio y la plantilla por defecto.
|
|||
|
||||
## TODO
|
||||
|
||||
* Reimplementar draft e incomplete (por qué eran distintos?)
|
||||
* Reimplementar subida de imagenes/archivos
|
||||
* Leer artículos a medida que se los necesita en lugar de todos juntos.
|
||||
* Reimplementar glosario (se crea un artículo por cada categoría
|
||||
utilizada)
|
||||
* Reimplementar orden de artículos (ver doc)
|
||||
* Reimplementar subida de imagenes/archivos
|
||||
* Reimplementar campo 'pre' y 'post' en los layouts.yml
|
||||
* Implementar autoría como un array
|
||||
* Reimplementar draft e incomplete (por qué eran distintos?)
|
||||
* Convertir idiomas disponibles a pestañas?
|
||||
* Implementar traducciones sin adivinar. Vincular artículos entre sí
|
||||
|
|
|
@ -58,4 +58,38 @@ class PostsControllerTest < ActionDispatch::IntegrationTest
|
|||
assert_equal 200, response.status
|
||||
assert_match @post.title.value, response.body
|
||||
end
|
||||
|
||||
test 'se pueden actualizar' do
|
||||
title = SecureRandom.hex
|
||||
|
||||
patch site_post_url(@site, @post.id), headers: @authorization,
|
||||
params: { post: { title: title } }
|
||||
|
||||
assert_equal 302, response.status
|
||||
|
||||
get site_posts_url(@site), headers: @authorization
|
||||
|
||||
assert_match title, response.body
|
||||
|
||||
site = Site.find @site.id
|
||||
assert site.posts.map { |p| p.title.value }.include?(title)
|
||||
end
|
||||
|
||||
test 'se pueden eliminar' do
|
||||
params = ActionController::Parameters.new(post: { author: ['hola'] })
|
||||
assert PostService.new(site: @site,
|
||||
usuarie: @usuarie,
|
||||
post: @post,
|
||||
params: params).update
|
||||
|
||||
delete site_post_url(@site, @post.id), headers: @authorization
|
||||
get site_posts_url(@site), headers: @authorization
|
||||
|
||||
site = Site.find @site.id
|
||||
|
||||
assert_not site.posts.include?(@post)
|
||||
assert @post.destroyed?
|
||||
assert_equal I18n.t('post_service.destroyed', title: @post.title.value),
|
||||
@site.repository.rugged.head.target.message
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue