diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb
new file mode 100644
index 000000000..efad5783e
--- /dev/null
+++ b/app/controllers/proposals_controller.rb
@@ -0,0 +1,38 @@
+class ProposalsController < ApplicationController
+ before_action :authenticate_user!, except: [:index, :show]
+
+ load_and_authorize_resource
+ respond_to :html, :js
+
+ def show
+ render text: ""
+ end
+
+ def new
+ @proposal = Proposal.new
+ load_featured_tags
+ end
+
+ def create
+ @proposal = Proposal.new(proposal_params)
+ @proposal.author = current_user
+
+ if @proposal.save_with_captcha
+ ahoy.track :proposal_created, proposal_id: @proposal.id
+ redirect_to @proposal, notice: t('flash.actions.create.notice', resource_name: 'proposal')
+ else
+ load_featured_tags
+ render :new
+ end
+ end
+
+ private
+
+ def proposal_params
+ params.require(:proposal).permit(:title, :question, :description, :tag_list, :terms_of_service, :captcha, :captcha_key)
+ end
+
+ def load_featured_tags
+ @featured_tags = ActsAsTaggableOn::Tag.where(featured: true)
+ end
+end
\ No newline at end of file
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 0d2ac3f8b..8249197e5 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -19,8 +19,14 @@ class Ability
debate.editable_by?(user)
end
+ can :read, Proposal
+ can :update, Proposal do |proposal|
+ proposal.editable_by?(user)
+ end
+
can :create, Comment
can :create, Debate
+ can :create, Proposal
can [:flag, :unflag], Comment
cannot [:flag, :unflag], Comment, user_id: user.id
diff --git a/app/models/proposal.rb b/app/models/proposal.rb
index 2cf86115d..e956e64e8 100644
--- a/app/models/proposal.rb
+++ b/app/models/proposal.rb
@@ -5,12 +5,15 @@ class Proposal < ActiveRecord::Base
has_many :comments, as: :commentable
has_many :flags, as: :flaggable
+ acts_as_taggable
+
validates :title, presence: true
+ validates :question, presence: true
validates :description, presence: true
validates :author, presence: true
- validates :question, presence: true
validate :validate_title_length
+ validate :validate_question_length
validate :validate_description_length
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create
@@ -22,6 +25,10 @@ class Proposal < ActiveRecord::Base
@@title_max_length ||= self.columns.find { |c| c.name == 'title' }.limit || 80
end
+ def self.question_max_length
+ 140
+ end
+
def self.description_max_length
6000
end
@@ -54,4 +61,12 @@ class Proposal < ActiveRecord::Base
validator.validate(self)
end
+ def validate_question_length
+ validator = ActiveModel::Validations::LengthValidator.new(
+ attributes: :title,
+ minimum: 10,
+ maximum: Proposal.question_max_length)
+ validator.validate(self)
+ end
+
end
diff --git a/app/views/proposals/_form.html.erb b/app/views/proposals/_form.html.erb
new file mode 100644
index 000000000..8d02b4a75
--- /dev/null
+++ b/app/views/proposals/_form.html.erb
@@ -0,0 +1,54 @@
+<%= form_for(@proposal) do |f| %>
+ <%= render 'shared/errors', resource: @proposal %>
+
+
+
+ <%= f.label :title, t("proposals.form.proposal_title") %>
+ <%= f.text_field :title, maxlength: Proposal.title_max_length, placeholder: t("proposals.form.proposal_title"), label: false %>
+
+
+
+ <%= f.label :question, t("proposals.form.proposal_question") %>
+ <%= f.text_field :question, maxlength: Proposal.question_max_length, placeholder: t("proposals.form.proposal_question"), label: false %>
+
+
+
+ <%= f.label :description, t("proposals.form.proposal_text") %>
+ <%= f.cktext_area :description, maxlength: Proposal.description_max_length, ckeditor: { language: I18n.locale }, label: false %>
+
+
+
+ <%= f.label :tag_list, t("proposals.form.tags_label") %>
+
<%= t("proposals.form.tags_instructions") %>
+
+ <% @featured_tags.each do |tag| %>
+ <%= tag.name %>
+ <% end %>
+
+ <%= f.text_field :tag_list, value: @proposal.tag_list.to_s, label: false, placeholder: t("proposals.form.tags_placeholder") %>
+
+
+
+ <% if @proposal.new_record? %>
+ <%= f.label :terms_of_service do %>
+ <%= f.check_box :terms_of_service, label: false %>
+
+ <%= t("form.accept_terms",
+ policy: link_to(t("form.policy"), "/privacy", target: "blank"),
+ conditions: link_to(t("form.conditions"), "/conditions", target: "blank")).html_safe %>
+
+ <% end %>
+ <% end %>
+
+
+
+ <%= f.simple_captcha input_html: { required: false } %>
+
+
+
+ <%= f.submit(class: "button radius", value: t("proposals.#{action_name}.form.submit_button")) %>
+
+
+<% end %>
+
+
diff --git a/app/views/proposals/new.html.erb b/app/views/proposals/new.html.erb
new file mode 100644
index 000000000..f478598b0
--- /dev/null
+++ b/app/views/proposals/new.html.erb
@@ -0,0 +1,28 @@
+
+
+
+ <%= link_to proposals_path, class: "left back" do %>
+
+ <%= t("proposals.new.back_link") %>
+ <% end %>
+
<%= t("proposals.new.start_new") %>
+
+ <%= t("proposals.new.info")%>
+ <%= link_to "/more_information", target: "_blank" do %>
+ <%= t("proposals.new.more_info")%>
+ <% end %>
+
+ <%= render "form" %>
+
+
+
+
+
<%= t("proposals.new.recommendations_title") %>
+
+ - <%= t("proposals.new.recommendation_one") %>
+ - <%= t("proposals.new.recommendation_two") %>
+ - <%= t("proposals.new.recommendation_three") %>
+ - <%= t("proposals.new.recommendation_four") %>
+
+
+
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index 94b1fa0c9..bedaf93a4 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -16,6 +16,12 @@ en:
description: Opinion
terms_of_service: Terms of service
title: Title
+ proposal:
+ author: Author
+ title: Title
+ question: Question
+ description: Description
+ terms_of_service: Terms of service
user:
email: Email
username: Username
diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml
index f566026de..e587a1f65 100644
--- a/config/locales/activerecord.es.yml
+++ b/config/locales/activerecord.es.yml
@@ -16,6 +16,12 @@ es:
description: Opinión
terms_of_service: Términos de servicio
title: Título
+ propuesta:
+ author: Autor
+ title: Título
+ question: Pregunta
+ description: Descripción
+ terms_of_service: Términos de servicio
user:
email: Correo electrónico
username: Nombre de usuario
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 98afaeb4f..e4b5e64b9 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -56,6 +56,7 @@ en:
conditions: "Terms of use"
user: account
debate: debate
+ proposal: proposal
verification::sms: phone
application:
alert:
@@ -144,6 +145,30 @@ en:
update:
form:
submit_button: "Save changes"
+ debates:
+ new:
+ start_new: Start a proposal
+ info: "A proposal is a discussion forum, not a proposal. And soon... we opened the section of citizen proposals."
+ more_info: "More info"
+ back_link: Back
+ recommendations_title: Tips for creating a proposal
+ recommendation_one: "Do not write the title of the debate or whole sentences in capital. On the Internet this is considered shouting. And nobody likes to scream."
+ recommendation_two: "Any discussion or comment that involves an illegal act will be eliminated, also intending to sabotage the debate spaces, everything else is permitted."
+ recommendation_three: "The harsh criticism are very welcome. This is a space of thought but we recommend preserving the elegance and intelligence. The world is better with them present."
+ recommendation_four: "Enjoy this space, voices that fill it, it is yours too."
+ form:
+ submit_button: "Start a proposal"
+ form:
+ proposal_title: Proposal title
+ proposal_question: Proposal question
+ proposal_text: Initial text for proposal
+ tags_label: Topics
+ tags_instructions: >
+ Tag this proposal. You can choose among our proposals on the list or add any other topic you want.
+ tags_placeholder: "Add topics writing them separated by ','"
+ create:
+ form:
+ submit_button: "Start a proposal"
comments:
form:
leave_comment: Write a comment
diff --git a/config/locales/es.yml b/config/locales/es.yml
index d2b51d551..e05eb48f9 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -56,6 +56,7 @@ es:
conditions: "Condiciones de uso"
user: la cuenta
debate: el debate
+ proposal: la propuesta
verification::sms: el teléfono
application:
alert:
@@ -144,6 +145,30 @@ es:
update:
form:
submit_button: "Guardar cambios"
+ proposals:
+ new:
+ start_new: Empezar una propuesta
+ info: "Una propuesta es un foro de discusión, no una propuesta ciudadana. Muy pronto abriremos la sección de propuestas ciudadanas, donde cualquiera podrá presentar propuestas y, si reciben apoyo, serán puestas en marcha por el Ayuntamiento."
+ more_info: "Más información"
+ back_link: Volver
+ recommendations_title: Recomendaciones para crear una propuesta
+ recommendation_one: "No escribas el título del debate o frases enteras en mayúsculas. En internet eso se considera gritar. Y a nadie le gusta que le griten."
+ recommendation_two: "Cualquier debate o comentario que implique una acción ilegal será eliminado, también los que tengan la intención de sabotear los espacios de debate, todo lo demás está permitido."
+ recommendation_three: "Las críticas despiadadas son muy bienvenidas. Este es un espacio de pensamiento. Pero te recomendamos conservar la elegancia y la inteligencia. El mundo es mejor con ellas presentes."
+ recommendation_four: "Disfruta de este espacio, de las voces que lo llenan, también es tuyo."
+ form:
+ submit_button: "Empieza una propuesta"
+ form:
+ proposal_title: Título de la propuesta
+ proposal_question: Pregunta de la propuesta
+ proposal_text: Texto inicial de la propuesta
+ tags_label: Temas
+ tags_instructions: >
+ Etiqueta este la propuesta. Puedes elegir entre nuestras propuestas o introducir las que desees.
+ tags_placeholder: "Escribe las etiquetas que desees separadas por ','"
+ create:
+ form:
+ submit_button: "Empieza una propuesta"
comments:
form:
leave_comment: Deja tu comentario
diff --git a/config/routes.rb b/config/routes.rb
index e434d71e8..7246c0807 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -45,6 +45,8 @@ Rails.application.routes.draw do
end
end
+ resources :proposals
+
resource :account, controller: "account", only: [:show, :update]
resource :verification, controller: "verification", only: [:show]