WIP de consensos y posiciones

* necesitamos autenticación para poder asignarles piratas
* falta test de crear posiciones
This commit is contained in:
fauno 2019-04-05 19:40:28 -03:00
parent 36d8a4d4dd
commit 3d489c0a0f
No known key found for this signature in database
GPG key ID: 456032D717A4CD9C
20 changed files with 220 additions and 7 deletions

2
.gitignore vendored
View file

@ -25,3 +25,5 @@
# Ignore master key for decrypting credentials and more.
/config/master.key
# Siempre da conflictos
/db/schema.rb

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
# Consensos
class ConsensosController < ApplicationController
# Podemos ver todos los consensos
def index
@consensos = Consenso.all.order(:created_at, :desc)
end
# Podemos ver uno solo
def show
@consenso = Consenso.find(params[:id])
return if @consenso
render json: {}, status: :not_found
end
# Podemos crear uno
def create
@consenso = Consenso.new(params.require(:consenso).permit(:titulo, :texto))
return if @consenso.save
render json: { errors: @consenso.errors.full_messages },
status: :unprocessable_entity
end
end

View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
# Las posiciones solo se pueden agregar a su consenso
class PosicionesController < ApplicationController
def create
@consenso = Consenso.find(params[:consenso_id])
@posicion = consenso.try(:posiciones).try(:build, posicion_params)
return if @posicion.try(:save)
render json: {}, status: :not_found
end
private
def posicion_params
params.require(:posicion).permit(:estado, :comentario)
end
end

9
app/models/consenso.rb Normal file
View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
# El consenso agrupa posiciones y textos
class Consenso < ApplicationRecord
# Es escrito por una pirata
belongs_to :pirata
# Agrupa muchas posiciones
has_many :posiciones
end

View file

@ -2,7 +2,12 @@
# Las piratas son las usuarias empoderadas del miniloom
class Pirata < ApplicationRecord
# Tiene una contraseña segura :P
# Puede proponer consensos
has_many :consensos
# Y tener posiciones
has_many :posiciones
# Y además una contraseña segura :P
has_secure_password
# Una por correo
validates :email, presence: true, uniqueness: true

19
app/models/posicion.rb Normal file
View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
# Una posición sobre un consenso
class Posicion < ApplicationRecord
# Tiene alguno de estos estados.
#
# TODO: Poder definirlos por configuración en lugar de hardcodearlos,
# pero al menos por ahora los podemos cambiar acá y no por todos lados
# como pasaba en Loomio
ESTADOS = %w[compromiso a_favor en_contra bloqueo indiferente].freeze
# Es hecha por una pirata
belongs_to :pirata
# Sobre un consenso
belongs_to :consenso
# Solo puede tener alguno de los estados definidos
validates :estado, inclusion: { in: Posicion::ESTADOS }
end

View file

@ -0,0 +1,5 @@
# frozen_string_literal: true
json.call(consenso, :id, :created_at, :titulo, :texto)
json.posiciones consenso.posiciones, partial: 'posiciones/posicion', as: :posicion

View file

@ -0,0 +1,3 @@
# frozen_string_literal: true
json.partial! @consenso, as: :consenso

View file

@ -0,0 +1,3 @@
# frozen_string_literal: true
json.consensos @consensos, partial: 'consensos/consenso', as: :consenso

View file

@ -0,0 +1,3 @@
# frozen_string_literal: true
json.partial! @consenso, as: :consenso

View file

@ -5,12 +5,10 @@
# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.plural 'posicion', 'posiciones'
inflect.singular 'posiciones', 'posicion'
end
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|

View file

@ -3,4 +3,9 @@
Rails.application.routes.draw do
# No queremos un índice de piratas
resources :piratas, only: %i[create]
# Podemos crear consensos pero no modificarlos
resources :consensos, only: %i[index show create] do
# Y solo le podemos agregar posiciones
resources :posiciones, only: %i[create]
end
end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
# Crear la tabla de consensos
class CreateConsensos < ActiveRecord::Migration[5.2]
def change
create_table :consensos do |t|
t.timestamps
t.belongs_to :pirata, index: true
t.string :titulo
t.text :texto
end
end
end

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
# Crear la tabla de posiciones
class CreatePosiciones < ActiveRecord::Migration[5.2]
def change
create_table :posiciones do |t|
t.timestamps
t.belongs_to :consenso, index: true
t.belongs_to :pirata, index: true
t.string :comentario
t.string :estado
end
end
end

View file

@ -0,0 +1,38 @@
# frozen_string_literal: true
require 'test_helper'
class ConsensosControllerTest < ActionDispatch::IntegrationTest
test 'se pueden mostrar' do
2.times { create :consenso }
get consensos_url, as: :json
body = JSON.parse(@response.body)
assert_equal 2, body['consensos'].size
end
test 'se puede ver uno solo' do
consenso = create :consenso
get consenso_url(consenso), as: :json
body = JSON.parse(@response.body)
assert_equal consenso.titulo, body['titulo']
end
test 'se pueden crear' do
post consensos_url, as: :json, params: {
consenso: {
titulo: 'hola',
texto: 'chau'
}
}
body = JSON.parse(@response.body)
consenso = Consenso.find(body['id'])
assert_equal 'hola', consenso.titulo
assert_equal 'chau', consenso.texto
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
require 'test_helper'
class PosicionesControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
FactoryBot.define do
factory :consenso do
pirata
titulo { 'Estamos a favor de la despenalización del aborto' }
texto { '...' }
end
end

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
FactoryBot.define do
factory :posicion do
pirata
consenso
estado { Posicion::ESTADOS.sample }
end
end

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'test_helper'
class ConsensoTest < ActiveSupport::TestCase
test 'se pueden crear' do
consenso = create :consenso
assert_equal true, consenso.valid?
end
end

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'test_helper'
class PosicionTest < ActiveSupport::TestCase
test 'se pueden crear' do
posicion = create :posicion
assert_equal true, posicion.valid?
end
end