barcas! al abordaje!
This commit is contained in:
parent
d669875815
commit
ac21341d49
18 changed files with 201 additions and 41 deletions
|
@ -6,17 +6,18 @@
|
|||
class ConsensosController < ApplicationController
|
||||
# Para cualquier acción necesitamos autenticación
|
||||
before_action :authenticate!
|
||||
before_action :find_barca!
|
||||
|
||||
# GET /consensos
|
||||
# GET /barcas/:barca_id/consensos
|
||||
#
|
||||
# Podemos ver todos los consensos
|
||||
# Podemos ver todos los consensos de una barca
|
||||
#
|
||||
# @return [Array] [ consensos ]
|
||||
def index
|
||||
@consensos = Consenso.all.order(:created_at, :desc)
|
||||
@consensos = @barca.consensos.order(:created_at, :desc)
|
||||
end
|
||||
|
||||
# GET /consensos/:id
|
||||
# GET /barcas/:barca_id/consensos/:id
|
||||
#
|
||||
# Podemos ver uno solo sabiendo su ID
|
||||
#
|
||||
|
@ -26,13 +27,13 @@ class ConsensosController < ApplicationController
|
|||
# pirata: @pirata,
|
||||
# posiciones: [] }
|
||||
def show
|
||||
@consenso = Consenso.find(params[:id])
|
||||
@consenso = @barca.consensos.find(params[:id])
|
||||
return if @consenso
|
||||
|
||||
render json: {}, status: :not_found
|
||||
end
|
||||
|
||||
# POST /consensos
|
||||
# POST /barcas/:barca_id/consensos
|
||||
#
|
||||
# Podemos crear uno, enviando un hash con todas las propiedades
|
||||
#
|
||||
|
@ -42,8 +43,8 @@ class ConsensosController < ApplicationController
|
|||
# pirata: @pirata,
|
||||
# posiciones: [] }
|
||||
def create
|
||||
@consenso = current_pirata.consensos
|
||||
.new(params.require(:consenso).permit(:titulo, :texto))
|
||||
@consenso = current_pirata.consensos.new(consenso_params)
|
||||
@consenso.barca = @barca
|
||||
|
||||
if @consenso.save
|
||||
render status: :created
|
||||
|
@ -53,7 +54,7 @@ class ConsensosController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# DELETE /consensos/:id
|
||||
# DELETE /barcas/:barca_id/consensos/:id
|
||||
#
|
||||
# Eliminar un consenso, solo si no tiene posiciones!
|
||||
#
|
||||
|
@ -63,7 +64,7 @@ class ConsensosController < ApplicationController
|
|||
# posiciones: [] }
|
||||
def destroy
|
||||
begin
|
||||
@consenso = Consenso.find(params[:id])
|
||||
@consenso = @barca.consensos.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render json: {}, status: :not_found
|
||||
return
|
||||
|
@ -75,4 +76,16 @@ class ConsensosController < ApplicationController
|
|||
render json: {}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Encuentra la barca en los parámetros
|
||||
def find_barca!
|
||||
@barca = Barca.find(params[:barca_id])
|
||||
end
|
||||
|
||||
# Parámetros permitidos
|
||||
def consenso_params
|
||||
params.require(:consenso).permit(:titulo, :texto)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
class PosicionesController < ApplicationController
|
||||
# Necesitamos autenticarnos
|
||||
before_action :authenticate!
|
||||
before_action :find_barca!
|
||||
|
||||
# POST /consensos/:consenso_id/posiciones
|
||||
# POST /barcas/:barca_id/consensos/:consenso_id/posiciones
|
||||
#
|
||||
# Crea una posición dentro de un consenso
|
||||
#
|
||||
|
@ -18,7 +19,7 @@ class PosicionesController < ApplicationController
|
|||
# @return [Hash] { id: @int, estado: @string, comentario: @string,
|
||||
# pirata: @pirata }
|
||||
def create
|
||||
@consenso = Consenso.find(params[:consenso_id])
|
||||
@consenso = @barca.consensos.find(params[:consenso_id])
|
||||
@posicion = @consenso.try(:posiciones).try(:build, posicion_params)
|
||||
@posicion.try(:pirata=, current_pirata)
|
||||
|
||||
|
@ -35,4 +36,8 @@ class PosicionesController < ApplicationController
|
|||
def posicion_params
|
||||
params.require(:posicion).permit(:estado, :comentario)
|
||||
end
|
||||
|
||||
def find_barca!
|
||||
@barca = Barca.find(params[:barca_id])
|
||||
end
|
||||
end
|
||||
|
|
16
app/models/barca.rb
Normal file
16
app/models/barca.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Las barcas agrupan consensos y piratas alrededor de un tema específico
|
||||
# o relación de afinidad
|
||||
class Barca < ApplicationRecord
|
||||
# Tiene muchos consensos
|
||||
has_many :consensos
|
||||
|
||||
# En realidad debería tener una sola tripulación que traiga muchas
|
||||
# piratas, pero rails es así
|
||||
has_many :tripulaciones, dependent: :destroy
|
||||
has_many :piratas, through: :tripulaciones
|
||||
|
||||
validates_uniqueness_of :nombre
|
||||
validates_presence_of :descripcion
|
||||
end
|
|
@ -7,4 +7,6 @@ class Consenso < ApplicationRecord
|
|||
belongs_to :pirata
|
||||
# Agrupa muchas posiciones
|
||||
has_many :posiciones
|
||||
# Pertenece a una barca
|
||||
belongs_to :barca
|
||||
end
|
||||
|
|
|
@ -7,6 +7,10 @@ class Pirata < ApplicationRecord
|
|||
# Y tener posiciones
|
||||
has_many :posiciones
|
||||
|
||||
# Puede participar en barcas
|
||||
has_many :tripulaciones
|
||||
has_many :barcas, through: :tripulaciones
|
||||
|
||||
# Y además una contraseña segura :P
|
||||
has_secure_password
|
||||
# Una por correo
|
||||
|
|
7
app/models/tripulacion.rb
Normal file
7
app/models/tripulacion.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# La tripulación de una barca
|
||||
class Tripulacion < ApplicationRecord
|
||||
belongs_to :barca
|
||||
belongs_to :pirata
|
||||
end
|
|
@ -10,6 +10,8 @@ ActiveSupport::Inflector.inflections(:en) do |inflect|
|
|||
inflect.singular 'posiciones', 'posicion'
|
||||
inflect.plural 'pirata', 'piratas'
|
||||
inflect.singular 'piratas', 'pirata'
|
||||
inflect.plural 'tripulacion', 'tripulaciones'
|
||||
inflect.singular 'tripulaciones', 'tripulacion'
|
||||
end
|
||||
|
||||
# These inflection rules are supported but not enabled by default:
|
||||
|
|
|
@ -4,9 +4,12 @@ Rails.application.routes.draw do
|
|||
get '/piratas/yo', to: 'piratas#yo'
|
||||
# No queremos un índice de piratas
|
||||
resources :piratas, only: %i[create]
|
||||
# Podemos crear barcas y dentro de ellas consensos
|
||||
resources :barcas, only: %i[index show create update destroy] do
|
||||
# Podemos crear consensos pero no modificarlos
|
||||
resources :consensos, only: %i[index show create destroy] do
|
||||
# Y solo le podemos agregar posiciones
|
||||
resources :posiciones, only: %i[create]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
12
db/migrate/20190803152627_create_barcas.rb
Normal file
12
db/migrate/20190803152627_create_barcas.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Crear las barcas
|
||||
class CreateBarcas < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :barcas do |t|
|
||||
t.timestamps
|
||||
t.string :nombre, unique: true
|
||||
t.text :descripcion
|
||||
end
|
||||
end
|
||||
end
|
12
db/migrate/20190803152706_create_tripulaciones.rb
Normal file
12
db/migrate/20190803152706_create_tripulaciones.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Las piratas abordan barcas a través de tripulaciones
|
||||
class CreateTripulaciones < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :tripulaciones do |t|
|
||||
t.timestamps
|
||||
t.belongs_to :barca, index: true
|
||||
t.belongs_to :pirata, index: true
|
||||
end
|
||||
end
|
||||
end
|
8
db/migrate/20190803152853_add_barca_to_consenso.rb
Normal file
8
db/migrate/20190803152853_add_barca_to_consenso.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Los consensos pertenecen a barcas
|
||||
class AddBarcaToConsenso < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_belongs_to :consensos, :barca, index: true
|
||||
end
|
||||
end
|
21
db/migrate/20190803154551_asamblea_general.rb
Normal file
21
db/migrate/20190803154551_asamblea_general.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Si no hay una barca, creamos una asamblea general!
|
||||
class AsambleaGeneral < ActiveRecord::Migration[5.2]
|
||||
def up
|
||||
return if Barca.all.count.positive?
|
||||
|
||||
barca = Barca.create(nombre: 'Asamblea General',
|
||||
descripcion: 'En la asamblea general tomamos todas las decisiones que no pasan por barcas.')
|
||||
|
||||
Pirata.all.find_each do |pirata|
|
||||
barca.piratas << pirata
|
||||
end
|
||||
|
||||
barca.save
|
||||
end
|
||||
|
||||
def down
|
||||
Barca.find_by(nombre: 'Asamblea General').destroy
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class ConsensosControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@barca = create :barca
|
||||
@pirata = create :pirata
|
||||
@auth = { Authorization: ActionController::HttpAuthentication::Basic
|
||||
.encode_credentials(@pirata.email, @pirata.password) }
|
||||
|
@ -9,10 +10,10 @@ class ConsensosControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
test 'se pueden mostrar' do
|
||||
2.times do
|
||||
create :consenso
|
||||
create :consenso, barca: @barca
|
||||
end
|
||||
|
||||
get consensos_url, as: :json, headers: @auth
|
||||
get barca_consensos_url(@barca), as: :json, headers: @auth
|
||||
body = JSON.parse(@response.body)
|
||||
|
||||
assert_equal 200, @response.status
|
||||
|
@ -21,7 +22,7 @@ class ConsensosControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
test 'al mostrar solo se ven las posiciones resumidas' do
|
||||
2.times do
|
||||
consenso = create :consenso
|
||||
consenso = create :consenso, barca: @barca
|
||||
pirata = create :pirata
|
||||
|
||||
3.times do
|
||||
|
@ -29,7 +30,7 @@ class ConsensosControllerTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
end
|
||||
|
||||
get consensos_url, as: :json, headers: @auth
|
||||
get barca_consensos_url(@barca), as: :json, headers: @auth
|
||||
body = JSON.parse(@response.body)
|
||||
|
||||
body['consensos'].each do |consenso|
|
||||
|
@ -40,7 +41,9 @@ class ConsensosControllerTest < ActionDispatch::IntegrationTest
|
|||
test 'se puede ver uno solo' do
|
||||
consenso = create :consenso, con_posiciones: 2
|
||||
|
||||
get consenso_url(consenso), as: :json, headers: @auth
|
||||
get barca_consenso_url(consenso.barca, consenso),
|
||||
as: :json,
|
||||
headers: @auth
|
||||
body = JSON.parse(@response.body)
|
||||
|
||||
assert_equal 200, @response.status
|
||||
|
@ -49,26 +52,22 @@ class ConsensosControllerTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
|
||||
test 'al ver uno solo se ve todo el historial de posiciones' do
|
||||
consenso = create :consenso
|
||||
consenso = create :consenso, barca: @barca
|
||||
pirata = create :pirata
|
||||
|
||||
3.times do
|
||||
create :posicion, consenso: consenso, pirata: pirata
|
||||
end
|
||||
|
||||
get consenso_url(consenso), as: :json, headers: @auth
|
||||
get barca_consenso_url(@barca, consenso), as: :json, headers: @auth
|
||||
body = JSON.parse(@response.body)
|
||||
|
||||
assert_equal 3, body['posiciones'].size
|
||||
end
|
||||
|
||||
test 'se pueden crear' do
|
||||
post consensos_url, as: :json, headers: @auth, params: {
|
||||
consenso: {
|
||||
titulo: 'hola',
|
||||
texto: 'chau'
|
||||
}
|
||||
}
|
||||
post barca_consensos_url(@barca), as: :json, headers: @auth,
|
||||
params: { consenso: { titulo: 'hola', texto: 'chau' } }
|
||||
|
||||
assert_equal 201, @response.status
|
||||
|
||||
|
@ -80,9 +79,10 @@ class ConsensosControllerTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
|
||||
test 'se pueden borrar si están vacíos' do
|
||||
consenso = create :consenso
|
||||
consenso = create :consenso, barca: @barca
|
||||
|
||||
delete consenso_url(consenso), as: :json, headers: @auth
|
||||
delete barca_consenso_url(@barca, consenso),
|
||||
as: :json, headers: @auth
|
||||
|
||||
assert_equal 200, @response.status
|
||||
|
||||
|
@ -91,10 +91,11 @@ class ConsensosControllerTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
|
||||
test 'no se pueden borrar si no están vacíos' do
|
||||
consenso = create :consenso
|
||||
consenso = create :consenso, barca: @barca
|
||||
create :posicion, consenso: consenso
|
||||
|
||||
delete consenso_url(consenso), as: :json, headers: @auth
|
||||
delete barca_consenso_url(@barca, consenso),
|
||||
as: :json, headers: @auth
|
||||
|
||||
assert_equal 422, @response.status
|
||||
end
|
||||
|
|
|
@ -4,22 +4,19 @@ require 'test_helper'
|
|||
|
||||
class PosicionesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@barca = create :barca
|
||||
@pirata = create :pirata
|
||||
@auth = { Authorization: ActionController::HttpAuthentication::Basic
|
||||
.encode_credentials(@pirata.email, @pirata.password) }
|
||||
end
|
||||
|
||||
test 'se pueden crear' do
|
||||
consenso = create :consenso
|
||||
consenso = create :consenso, barca: @barca
|
||||
estado = Posicion::ESTADOS.sample
|
||||
|
||||
post consenso_posiciones_url(consenso), as: :json, headers: @auth,
|
||||
params: {
|
||||
posicion: {
|
||||
estado: estado,
|
||||
comentario: 'porque me place'
|
||||
}
|
||||
}
|
||||
post barca_consenso_posiciones_url(@barca, consenso),
|
||||
as: :json, headers: @auth,
|
||||
params: { posicion: { estado: estado, comentario: 'porque me place' } }
|
||||
|
||||
assert_equal 201, @response.status
|
||||
|
||||
|
|
16
test/factories/barca.rb
Normal file
16
test/factories/barca.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :barca do
|
||||
nombre { SecureRandom.hex }
|
||||
descripcion { SecureRandom.hex }
|
||||
|
||||
transient do
|
||||
tripulacion { 0 }
|
||||
end
|
||||
|
||||
after :create do |barca, evaluator|
|
||||
create_list(:tripulacion, evaluator.tripulacion, barca: barca)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
FactoryBot.define do
|
||||
factory :consenso do
|
||||
barca
|
||||
pirata
|
||||
titulo { 'Estamos a favor de la despenalización del aborto' }
|
||||
texto { '...' }
|
||||
|
|
8
test/factories/tripulacion.rb
Normal file
8
test/factories/tripulacion.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :tripulacion do
|
||||
barca
|
||||
pirata
|
||||
end
|
||||
end
|
32
test/models/barca_test.rb
Normal file
32
test/models/barca_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class BarcaTest < ActiveSupport::TestCase
|
||||
test 'se pueden crear' do
|
||||
barca = create :barca
|
||||
|
||||
assert_equal true, barca.valid?
|
||||
end
|
||||
|
||||
test 'pueden tener tripulacion' do
|
||||
barca = create :barca, tripulacion: 3
|
||||
|
||||
assert_equal 3, barca.tripulaciones.count
|
||||
assert_equal 3, barca.piratas.count
|
||||
end
|
||||
|
||||
test 'el nombre tiene que ser único' do
|
||||
create :barca, nombre: 'hola'
|
||||
|
||||
barca = build :barca, nombre: 'hola'
|
||||
|
||||
assert barca.invalid?
|
||||
end
|
||||
|
||||
test 'al eliminar la barca se elimina su tripulación' do
|
||||
barca = create :barca, tripulacion: 3
|
||||
|
||||
assert barca.destroy
|
||||
assert_equal 3, Pirata.all.count
|
||||
assert Tripulacion.all.count.zero?
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue