diff --git a/.gitignore b/.gitignore index 865001781..31491de9d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,10 @@ # Mac finder artifacts .DS_Store + +# Intellij IDE project settings +/.idea + .ruby-gemset public/sitemap.xml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5a6639f0b..c5073a7a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,12 +2,18 @@ ## Core team members -* Raimond García [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000) -* Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu) -* Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik) -* Alberto García Cabeza [github](https://github.com/decabeza) -* Alberto Calderón [github](https://github.com/bertocq) | [twitter](https://twitter.com/bertocq) -* Maria Checa [github](https://github.com/MariaCheca) +* [Alberto García](https://github.com/decabeza) +* [Javi Martín](https://github.com/javierm) +* [Julián Herrero](https://github.com/microweb10) +* [Raimond García](https://github.com/voodoorai2000) + +## All other contributors + +In addition to the formal team, there are [over a hundred contributors](https://github.com/consul/consul/graphs/contributors). Thank you so much for your code! Big thanks too to the people that contribute in many other ways including documentation, translations, evangelism, dev ops, communication, organizing and more! + +Finally a special thanks to the former core team members. Lovingly known as The Alumni: + +[Juanjo Bazán](https://github.com/xuanxu), [Enrique García Cota](https://github.com/kikito), [Alberto Calderón](https://github.com/bertocq), [María Checa](https://github.com/mariacheca) ## Code of conduct diff --git a/CONTRIBUTING_ES.md b/CONTRIBUTING_ES.md index 826e23a79..bdfcdf91c 100644 --- a/CONTRIBUTING_ES.md +++ b/CONTRIBUTING_ES.md @@ -1,13 +1,19 @@ -# Cómo Contribuir a este Projecto +# Cómo Contribuir a este Proyecto -## Miembros del equipo +## Miembros del equipo core -* Raimond García [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000) -* Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu) -* Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik) -* Alberto García Cabeza [github](https://github.com/decabeza) -* Alberto Calderón [github](https://github.com/bertocq) | [twitter](https://twitter.com/bertocq) -* Maria Checa [github](https://github.com/MariaCheca) +* [Alberto García](https://github.com/decabeza) +* [Javi Martín](https://github.com/javierm) +* [Julián Herrero](https://github.com/microweb10) +* [Raimond García](https://github.com/voodoorai2000) + +## Todos los demás contribuidores + +Además del equipo formal, hay [más de cien contribuidores](https://github.com/consul/consul/graphs/contributors). ¡Muchas gracias por vuestro código! También estamos muy agradecidos a las personas que contribuyen de otras formas, incluida la documentación, traducciones, evangelismo, administración de sistemas, comunicación, organización y más. + +Finalmente, un agradecimiento especial a los antiguos miembros del equipo core. Conocidos con cariño como El Alumni: + +[Juanjo Bazán](https://github.com/xuanxu), [Enrique García Cota](https://github.com/kikito), [Alberto Calderón](https://github.com/bertocq), [María Checa](https://github.com/mariacheca) ## Código de conducta diff --git a/Gemfile b/Gemfile index 3924093fd..4db164f3c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" -gem "rails", "4.2.11.1" +gem "rails", "5.0.7.2" gem "acts-as-taggable-on", "~> 5.0.0" gem "acts_as_votable", "~> 0.11.1" @@ -16,11 +16,13 @@ gem "coffee-rails", "~> 4.2.2" gem "daemons", "~> 1.2.4" gem "dalli", "~> 2.7.6" gem "delayed_job_active_record", "~> 4.1.3" -gem "devise", "~> 3.5.7" -gem "devise-async", "~> 0.10.2" -gem "devise_security_extension", "~> 0.10.0" +gem "devise", "~> 4.6.0" +gem "devise-async", "~> 1.0.0" +gem "devise_security_extension", git: "https://github.com/phatworx/devise_security_extension.git" #, "~> 0.10" gem "foundation-rails", "~> 6.4.3.0" gem "foundation_rails_helper", "~> 2.0.0" +gem "globalize", "~> 5.2.0" +gem "globalize-accessors", "~> 0.2.1" gem "graphiql-rails", "~> 1.4.1" gem "graphql", "~> 1.7.8" gem "groupdate", "~> 3.2.0" @@ -39,6 +41,7 @@ gem "paperclip", "~> 5.2.1" gem "paranoia", "~> 2.4.1" gem "pg", "~> 0.21.0" gem "pg_search", "~> 2.0.1" +gem "record_tag_helper", "~> 1.0" gem "redcarpet", "~> 3.4.0" gem "responders", "~> 2.4.0" gem "rinku", "~> 2.0.2", require: "rails_rinku" @@ -53,8 +56,6 @@ gem "turnout", "~> 2.4.0" gem "uglifier", "~> 4.1.2" gem "unicorn", "~> 5.4.1" gem "whenever", "~> 0.10.0", require: false -gem "globalize", "~> 5.0.0" -gem "globalize-accessors", "~> 0.2.1" gem "recipient_interceptor", "~> 0.2.0" gem "wkhtmltopdf-binary", "~> 0.12.4" gem "wicked_pdf", "~> 1.1.0" @@ -73,7 +74,6 @@ group :development, :test do gem "knapsack_pro", "~> 1.1.0" gem "launchy", "~> 2.4.3" gem "letter_opener_web", "~> 1.3.4" - gem "quiet_assets", "~> 1.1.0" gem "spring", "~> 2.0.1" gem "spring-commands-rspec", "~> 1.0.4" end @@ -84,7 +84,7 @@ group :test do gem "database_cleaner", "~> 1.7.0" gem "email_spec", "~> 2.1.0" gem "rspec-rails", "~> 3.8" - gem "selenium-webdriver", "~> 3.10" + gem "selenium-webdriver", "~> 3.141" end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index d1e2865ca..a01856e53 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,40 +1,51 @@ +GIT + remote: https://github.com/phatworx/devise_security_extension.git + revision: b2ee978af7d49f0fb0e7271c6ac074dfb4d39353 + specs: + devise_security_extension (0.10.0) + devise (>= 3.0.0, < 5.0) + railties (>= 3.2.6, < 6.0) + GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ specs: - actionmailer (4.2.11.1) - actionpack (= 4.2.11.1) - actionview (= 4.2.11.1) - activejob (= 4.2.11.1) + actioncable (5.0.7.2) + actionpack (= 5.0.7.2) + nio4r (>= 1.2, < 3.0) + websocket-driver (~> 0.6.1) + actionmailer (5.0.7.2) + actionpack (= 5.0.7.2) + actionview (= 5.0.7.2) + activejob (= 5.0.7.2) mail (~> 2.5, >= 2.5.4) - rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.11.1) - actionview (= 4.2.11.1) - activesupport (= 4.2.11.1) - rack (~> 1.6) - rack-test (~> 0.6.2) - rails-dom-testing (~> 1.0, >= 1.0.5) + rails-dom-testing (~> 2.0) + actionpack (5.0.7.2) + actionview (= 5.0.7.2) + activesupport (= 5.0.7.2) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.11.1) - activesupport (= 4.2.11.1) + actionview (5.0.7.2) + activesupport (= 5.0.7.2) builder (~> 3.1) erubis (~> 2.7.0) - rails-dom-testing (~> 1.0, >= 1.0.5) + rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (4.2.11.1) - activesupport (= 4.2.11.1) - globalid (>= 0.3.0) - activemodel (4.2.11.1) - activesupport (= 4.2.11.1) - builder (~> 3.1) - activerecord (4.2.11.1) - activemodel (= 4.2.11.1) - activesupport (= 4.2.11.1) - arel (~> 6.0) - activesupport (4.2.11.1) - i18n (~> 0.7) + activejob (5.0.7.2) + activesupport (= 5.0.7.2) + globalid (>= 0.3.6) + activemodel (5.0.7.2) + activesupport (= 5.0.7.2) + activerecord (5.0.7.2) + activemodel (= 5.0.7.2) + activesupport (= 5.0.7.2) + arel (~> 7.0) + activesupport (5.0.7.2) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) acts-as-taggable-on (5.0.0) activerecord (>= 4.2.8) @@ -59,7 +70,7 @@ GEM nokogiri ancestry (3.0.2) activerecord (>= 3.2.0) - arel (6.0.4) + arel (7.1.4) ast (2.4.0) autoprefixer-rails (9.1.4) execjs @@ -67,7 +78,7 @@ GEM babel-transpiler (0.7.0) babel-source (>= 4.0, < 6) execjs (~> 2.0) - bcrypt (3.1.11) + bcrypt (3.1.12) best_in_place (3.0.3) actionpack (>= 3.2) railties (>= 3.2) @@ -107,7 +118,7 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (>= 2.0, < 4.0) - childprocess (0.8.0) + childprocess (0.9.0) ffi (~> 1.0, >= 1.0.11) chronic (0.10.2) ckeditor (4.2.4) @@ -141,18 +152,15 @@ GEM delayed_job_active_record (4.1.3) activerecord (>= 3.0, < 5.3) delayed_job (>= 3.0, < 5) - devise (3.5.10) + devise (4.6.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 3.2.6, < 5) + railties (>= 4.1.0, < 6.0) responders - thread_safe (~> 0.1) warden (~> 1.2.3) - devise-async (0.10.2) - devise (>= 3.2, < 4.0) - devise_security_extension (0.10.0) - devise (>= 3.0.0, < 4.0) - railties (>= 3.2.6, < 5.0) + devise-async (1.0.0) + activejob (>= 5.0) + devise (>= 4.0) diff-lcs (1.3) docile (1.3.1) email_spec (2.1.1) @@ -177,9 +185,9 @@ GEM railties (>= 3.0.0) faker (1.8.7) i18n (>= 0.7) - faraday (0.12.1) + faraday (0.12.2) multipart-post (>= 1.2, < 3) - ffi (1.9.25) + ffi (1.10.0) foundation-rails (6.4.3.0) railties (>= 3.1.0) sass (>= 3.3.0, < 3.5) @@ -190,12 +198,13 @@ GEM activesupport (>= 4.1) railties (>= 4.1) tzinfo (~> 1.2, >= 1.2.2) - geocoder (1.4.4) + geocoder (1.4.5) globalid (0.4.2) activesupport (>= 4.2.0) - globalize (5.0.1) - activemodel (>= 4.2.0, < 4.3) - activerecord (>= 4.2.0, < 4.3) + globalize (5.2.0) + activemodel (>= 4.2, < 5.3) + activerecord (>= 4.2, < 5.3) + request_store (~> 1.0) globalize-accessors (0.2.1) globalize (~> 5.0, >= 5.0.0) graphiql-rails (1.4.8) @@ -272,6 +281,7 @@ GEM kramdown (~> 1.12, >= 1.12.0) mixlib-cli (~> 1.7, >= 1.7.0) mixlib-config (~> 2.2, >= 2.2.1) + method_source (0.9.2) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) @@ -289,10 +299,11 @@ GEM net-ssh (>= 2.6.5) net-ssh (5.0.2) newrelic_rpm (4.1.0.333) - nokogiri (1.10.1) + nio4r (2.3.1) + nokogiri (1.10.2) mini_portile2 (~> 2.4.0) nori (2.6.0) - oauth (0.5.3) + oauth (0.5.4) oauth2 (1.4.0) faraday (>= 0.8, < 0.13) jwt (~> 1.0) @@ -312,8 +323,8 @@ GEM omniauth-oauth (1.1.0) oauth omniauth (~> 1.0) - omniauth-oauth2 (1.4.0) - oauth2 (~> 1.0) + omniauth-oauth2 (1.5.0) + oauth2 (~> 1.1) omniauth (~> 1.2) omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) @@ -337,39 +348,36 @@ GEM arel (>= 6) powerpack (0.1.2) public_suffix (3.0.3) - quiet_assets (1.1.0) - railties (>= 3.1, < 5.0) - rack (1.6.11) + rack (2.0.6) rack-accept (0.4.5) rack (>= 0.4) rack-attack (5.0.1) rack rack-test (0.6.3) rack (>= 1.0) - rails (4.2.11.1) - actionmailer (= 4.2.11.1) - actionpack (= 4.2.11.1) - actionview (= 4.2.11.1) - activejob (= 4.2.11.1) - activemodel (= 4.2.11.1) - activerecord (= 4.2.11.1) - activesupport (= 4.2.11.1) - bundler (>= 1.3.0, < 2.0) - railties (= 4.2.11.1) - sprockets-rails - rails-assets-leaflet (1.1.0) + rails (5.0.7.2) + actioncable (= 5.0.7.2) + actionmailer (= 5.0.7.2) + actionpack (= 5.0.7.2) + actionview (= 5.0.7.2) + activejob (= 5.0.7.2) + activemodel (= 5.0.7.2) + activerecord (= 5.0.7.2) + activesupport (= 5.0.7.2) + bundler (>= 1.3.0) + railties (= 5.0.7.2) + sprockets-rails (>= 2.0.0) + rails-assets-leaflet (1.2.0) rails-assets-markdown-it (8.2.2) - rails-deprecated_sanitizer (1.0.3) - activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.9) - activesupport (>= 4.2.0, < 5.0) - nokogiri (~> 1.6) - rails-deprecated_sanitizer (>= 1.0.1) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) rails-html-sanitizer (1.0.4) loofah (~> 2.2, >= 2.2.2) - railties (4.2.11.1) - actionpack (= 4.2.11.1) - activesupport (= 4.2.11.1) + railties (5.0.7.2) + actionpack (= 5.0.7.2) + activesupport (= 5.0.7.2) + method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (3.0.0) @@ -377,12 +385,15 @@ GEM rake (12.3.2) recipient_interceptor (0.2.0) mail + record_tag_helper (1.0.0) + actionview (~> 5.x) redcarpet (3.4.0) referer-parser (0.3.0) - request_store (1.3.2) - responders (2.4.0) - actionpack (>= 4.2.0, < 5.3) - railties (>= 4.2.0, < 5.3) + request_store (1.4.0) + rack (>= 1.4) + responders (2.4.1) + actionpack (>= 4.2.0, < 6.0) + railties (>= 4.2.0, < 6.0) rinku (2.0.4) rollbar (2.18.0) multi_json @@ -394,7 +405,7 @@ GEM rspec-mocks (3.8.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) - rspec-rails (3.8.1) + rspec-rails (3.8.2) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) @@ -437,9 +448,9 @@ GEM scss_lint (0.55.0) rake (>= 0.9, < 13) sass (~> 3.4.20) - selenium-webdriver (3.10.0) + selenium-webdriver (3.141.0) childprocess (~> 0.5) - rubyzip (~> 1.2) + rubyzip (~> 1.2, >= 1.2.2) simplecov (0.16.1) docile (~> 1.1) json (>= 1.8, < 3) @@ -478,9 +489,9 @@ GEM tilt (2.0.8) tins (1.16.3) tomlrb (1.2.7) - turbolinks (2.5.3) + turbolinks (2.5.4) coffee-rails - turnout (2.4.0) + turnout (2.4.1) i18n (~> 0.7) rack (>= 1.3, < 3) rack-accept (~> 0.4) @@ -494,10 +505,10 @@ GEM kgio (~> 2.6) raindrops (~> 0.7) uniform_notifier (1.11.0) - user_agent_parser (2.3.1) + user_agent_parser (2.4.1) uuidtools (2.1.5) - warden (1.2.7) - rack (>= 1.0) + warden (1.2.8) + rack (>= 2.0.6) wasabi (3.5.0) httpi (~> 2.0) nokogiri (>= 1.4.2) @@ -505,6 +516,9 @@ GEM activemodel (>= 4.2) debug_inspector railties (>= 4.2) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.3) whenever (0.10.0) chronic (>= 0.6.3) wicked_pdf (1.1.0) @@ -539,16 +553,16 @@ DEPENDENCIES dalli (~> 2.7.6) database_cleaner (~> 1.7.0) delayed_job_active_record (~> 4.1.3) - devise (~> 3.5.7) - devise-async (~> 0.10.2) - devise_security_extension (~> 0.10.0) + devise (~> 4.6.0) + devise-async (~> 1.0.0) + devise_security_extension! email_spec (~> 2.1.0) erb_lint factory_bot_rails (~> 4.8.2) faker (~> 1.8.7) foundation-rails (~> 6.4.3.0) foundation_rails_helper (~> 2.0.0) - globalize (~> 5.0.0) + globalize (~> 5.2.0) globalize-accessors (~> 0.2.1) graphiql-rails (~> 1.4.1) graphql (~> 1.7.8) @@ -573,11 +587,11 @@ DEPENDENCIES paranoia (~> 2.4.1) pg (~> 0.21.0) pg_search (~> 2.0.1) - quiet_assets (~> 1.1.0) - rails (= 4.2.11.1) + rails (= 5.0.7.2) rails-assets-leaflet! rails-assets-markdown-it (~> 8.2.1)! recipient_interceptor (~> 0.2.0) + record_tag_helper (~> 1.0) redcarpet (~> 3.4.0) responders (~> 2.4.0) rinku (~> 2.0.2) @@ -589,7 +603,7 @@ DEPENDENCIES sass-rails (~> 5.0, >= 5.0.4) savon (~> 2.12.0) scss_lint (~> 0.55.0) - selenium-webdriver (~> 3.10) + selenium-webdriver (~> 3.141) sitemap_generator (~> 6.0.1) social-share-button (~> 1.1) spring (~> 2.0.1) diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb index a451d67a5..156d74f34 100644 --- a/app/controllers/admin/budget_investments_controller.rb +++ b/app/controllers/admin/budget_investments_controller.rb @@ -39,7 +39,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController if @investment.update(budget_investment_params) redirect_to admin_budget_budget_investment_path(@budget, @investment, - Budget::Investment.filter_params(params)), + Budget::Investment.filter_params(params).to_h), notice: t("flash.actions.update.budget_investment") else load_admins @@ -69,7 +69,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController end def resource_name - resource_model.parameterize("_") + resource_model.parameterize(separator: "_") end def load_investments @@ -107,7 +107,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController end def load_tags - @tags = Budget::Investment.tags_on(:valuation).order(:name).uniq + @tags = Budget::Investment.tags_on(:valuation).order(:name).distinct end def load_ballot diff --git a/app/controllers/admin/legislation/homepages_controller.rb b/app/controllers/admin/legislation/homepages_controller.rb index 6b2084448..72ff890e9 100644 --- a/app/controllers/admin/legislation/homepages_controller.rb +++ b/app/controllers/admin/legislation/homepages_controller.rb @@ -9,7 +9,8 @@ class Admin::Legislation::HomepagesController < Admin::Legislation::BaseControll def update if @process.update(process_params) link = legislation_process_path(@process).html_safe - redirect_to :back, notice: t("admin.legislation.processes.update.notice", link: link) + redirect_back(fallback_location: (request.referrer || root_path), + notice: t("admin.legislation.processes.update.notice", link: link)) else flash.now[:error] = t("admin.legislation.processes.update.error") render :edit diff --git a/app/controllers/admin/legislation/processes_controller.rb b/app/controllers/admin/legislation/processes_controller.rb index 6c0d2ea6f..f0b9c6de3 100644 --- a/app/controllers/admin/legislation/processes_controller.rb +++ b/app/controllers/admin/legislation/processes_controller.rb @@ -27,7 +27,8 @@ class Admin::Legislation::ProcessesController < Admin::Legislation::BaseControll set_tag_list link = legislation_process_path(@process).html_safe - redirect_to :back, notice: t("admin.legislation.processes.update.notice", link: link) + redirect_back(fallback_location: (request.referrer || root_path), + notice: t("admin.legislation.processes.update.notice", link: link)) else flash.now[:error] = t("admin.legislation.processes.update.error") render :edit diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index b012aad38..a543093b2 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -7,13 +7,11 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController before_action :load_geozones, only: [:new, :create, :edit, :update] def index - @polls = Poll.order(starts_at: :desc) + @polls = Poll.not_budget.order(starts_at: :desc) end def show - @poll = Poll.includes(:questions). - order("poll_questions.title"). - find(params[:id]) + @poll = Poll.find(params[:id]) end def new @@ -22,7 +20,12 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController def create @poll = Poll.new(poll_params.merge(author: current_user)) if @poll.save - redirect_to [:admin, @poll], notice: t("flash.actions.create.poll") + notice = t("flash.actions.create.poll") + if @poll.budget.present? + redirect_to admin_poll_booth_assignments_path(@poll), notice: notice + else + redirect_to [:admin, @poll], notice: notice + end else render :new end @@ -62,8 +65,9 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController end def poll_params + image_attributes = [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy] attributes = [:name, :starts_at, :ends_at, :geozone_restricted, :results_enabled, - :stats_enabled, geozone_ids: [], + :stats_enabled, :budget_id, geozone_ids: [], image_attributes: image_attributes] params.require(:poll).permit(*attributes, translation_params(Poll)) end diff --git a/app/controllers/admin/poll/questions/answers/videos_controller.rb b/app/controllers/admin/poll/questions/answers/videos_controller.rb index e9262b6dd..7628ab081 100644 --- a/app/controllers/admin/poll/questions/answers/videos_controller.rb +++ b/app/controllers/admin/poll/questions/answers/videos_controller.rb @@ -38,7 +38,7 @@ class Admin::Poll::Questions::Answers::VideosController < Admin::Poll::BaseContr else t("flash.actions.destroy.error") end - redirect_to :back, notice: notice + redirect_back(fallback_location: (request.referrer || root_path), notice: notice) end private diff --git a/app/controllers/admin/poll/questions_controller.rb b/app/controllers/admin/poll/questions_controller.rb index ed39862b2..769a7998c 100644 --- a/app/controllers/admin/poll/questions_controller.rb +++ b/app/controllers/admin/poll/questions_controller.rb @@ -6,7 +6,7 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController load_and_authorize_resource :question, class: "Poll::Question" def index - @polls = Poll.all + @polls = Poll.not_budget @search = search_params[:search] @questions = @questions.search(search_params).page(params[:page]).order("created_at DESC") diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 277ec91a6..85e765cb4 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -46,7 +46,7 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz .keys languages_to_delete.each do |locale| - I18nContentTranslation.destroy_all(locale: locale) + I18nContentTranslation.where(locale: locale).destroy_all end end diff --git a/app/controllers/admin/spending_proposals_controller.rb b/app/controllers/admin/spending_proposals_controller.rb index 899a32486..4ef96a3c0 100644 --- a/app/controllers/admin/spending_proposals_controller.rb +++ b/app/controllers/admin/spending_proposals_controller.rb @@ -1,5 +1,6 @@ class Admin::SpendingProposalsController < Admin::BaseController include FeatureFlags + before_action :load_filter_params feature_flag :spending_proposals has_filters %w{valuation_open without_admin managed valuating valuation_finished all}, only: :index @@ -7,7 +8,7 @@ class Admin::SpendingProposalsController < Admin::BaseController load_and_authorize_resource def index - @spending_proposals = SpendingProposal.scoped_filter(params, @current_filter) + @spending_proposals = SpendingProposal.scoped_filter(filter_params, @current_filter) .order(cached_votes_up: :desc, created_at: :desc) .page(params[:page]) end @@ -23,7 +24,7 @@ class Admin::SpendingProposalsController < Admin::BaseController def update if @spending_proposal.update(spending_proposal_params) - redirect_to admin_spending_proposal_path(@spending_proposal, SpendingProposal.filter_params(params)), + redirect_to admin_spending_proposal_path(@spending_proposal, filter_params), notice: t("flash.actions.update.spending_proposal") else load_admins @@ -46,6 +47,14 @@ class Admin::SpendingProposalsController < Admin::BaseController :administrator_id, :tag_list, valuator_ids: []) end + def filter_params + params.permit(:geozone_id, :administrator_id, :tag_name, :valuator_id) + end + + def load_filter_params + @filter_params ||= filter_params + end + def load_admins @admins = Administrator.includes(:user).all end diff --git a/app/controllers/admin/widget/feeds_controller.rb b/app/controllers/admin/widget/feeds_controller.rb index ab4a5a474..2becdf28a 100644 --- a/app/controllers/admin/widget/feeds_controller.rb +++ b/app/controllers/admin/widget/feeds_controller.rb @@ -4,7 +4,7 @@ class Admin::Widget::FeedsController < Admin::BaseController @feed = ::Widget::Feed.find(params[:id]) @feed.update(feed_params) - render nothing: true + head :ok end private @@ -13,4 +13,4 @@ class Admin::Widget::FeedsController < Admin::BaseController params.require(:widget_feed).permit(:limit) end -end \ No newline at end of file +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5df842899..38ce20f34 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,6 +10,7 @@ class ApplicationController < ActionController::Base before_action :set_locale before_action :track_email_campaign before_action :set_return_url + before_action :set_fallbacks_to_all_available_locales check_authorization unless: :devise_controller? self.responder = ApplicationResponder @@ -128,4 +129,8 @@ class ApplicationController < ActionController::Base def current_budget Budget.current end + + def set_fallbacks_to_all_available_locales + Globalize.set_fallbacks_to_all_available_locales + end end diff --git a/app/controllers/budgets/executions_controller.rb b/app/controllers/budgets/executions_controller.rb index 54decebee..0d4c25134 100644 --- a/app/controllers/budgets/executions_controller.rb +++ b/app/controllers/budgets/executions_controller.rb @@ -19,7 +19,7 @@ module Budgets .group_by(&:heading) else @budget.investments.winners - .joins(:milestones).includes(:milestones) + .joins(milestones: :translations) .distinct.group_by(&:heading) end end diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb index 05f0e8f96..78185b5b4 100644 --- a/app/controllers/follows_controller.rb +++ b/app/controllers/follows_controller.rb @@ -22,7 +22,7 @@ class FollowsController < ApplicationController end def followable_translation_key(followable) - followable.class.name.parameterize("_") + followable.class.name.parameterize(separator: "_") end end diff --git a/app/controllers/legislation/annotations_controller.rb b/app/controllers/legislation/annotations_controller.rb index 587a9578e..a25248032 100644 --- a/app/controllers/legislation/annotations_controller.rb +++ b/app/controllers/legislation/annotations_controller.rb @@ -1,4 +1,4 @@ -class Legislation::AnnotationsController < ApplicationController +class Legislation::AnnotationsController < Legislation::BaseController skip_before_action :verify_authenticity_token before_action :authenticate_user!, only: [:create, :new_comment] diff --git a/app/controllers/management/document_verifications_controller.rb b/app/controllers/management/document_verifications_controller.rb index 1b3abc398..cb7ff1d7e 100644 --- a/app/controllers/management/document_verifications_controller.rb +++ b/app/controllers/management/document_verifications_controller.rb @@ -16,7 +16,7 @@ class Management::DocumentVerificationsController < Management::BaseController elsif @document_verification.user? render :new elsif @document_verification.in_census? - redirect_to new_management_email_verification_path(email_verification: document_verification_params) + redirect_to new_management_email_verification_path(email_verification: document_verification_params.to_h) else render :invalid_document end diff --git a/app/controllers/management/users_controller.rb b/app/controllers/management/users_controller.rb index 5f67aa506..7a063e82e 100644 --- a/app/controllers/management/users_controller.rb +++ b/app/controllers/management/users_controller.rb @@ -17,7 +17,7 @@ class Management::UsersController < Management::BaseController @user.residence_verified_at = Time.current @user.verified_at = Time.current - if @user.save then + if @user.save render :show else render :new diff --git a/app/controllers/officing/ballot_sheets_controller.rb b/app/controllers/officing/ballot_sheets_controller.rb new file mode 100644 index 000000000..9a4f08401 --- /dev/null +++ b/app/controllers/officing/ballot_sheets_controller.rb @@ -0,0 +1,70 @@ +class Officing::BallotSheetsController < Officing::BaseController + + before_action :verify_booth + before_action :load_poll + before_action :load_officer_assignments, only: [:new, :create] + + helper_method :namespace + + def index + load_ballot_sheets + end + + def show + load_ballot_sheet + end + + def new + end + + def create + load_officer_assignment + + @ballot_sheet = Poll::BallotSheet.new(ballot_sheet_params) + + if @ballot_sheet.save + redirect_to officing_poll_ballot_sheet_path(@poll, @ballot_sheet) + else + flash.now[:alert] = @ballot_sheet.errors.full_messages.join(", ") + render :new + end + end + + private + + def namespace + "officing" + end + + def load_poll + @poll = Poll.find(params[:poll_id]) + end + + def load_ballot_sheets + @ballot_sheets = Poll::BallotSheet.where(poll: @poll) + end + + def load_ballot_sheet + @ballot_sheet = Poll::BallotSheet.find(params[:id]) + end + + def load_officer_assignments + @officer_assignments = ::Poll::OfficerAssignment. + includes(booth_assignment: [:booth]). + joins(:booth_assignment). + final. + where(id: current_user.poll_officer.officer_assignment_ids). + where("poll_booth_assignments.poll_id = ?", @poll.id). + where(date: Date.current) + end + + def load_officer_assignment + @officer_assignment = current_user.poll_officer.officer_assignments.final + .find_by(id: ballot_sheet_params[:officer_assignment_id]) + end + + def ballot_sheet_params + params.permit(:data, :poll_id, :officer_assignment_id) + end + +end diff --git a/app/controllers/officing/base_controller.rb b/app/controllers/officing/base_controller.rb index 58ba3c8b2..e73f2b696 100644 --- a/app/controllers/officing/base_controller.rb +++ b/app/controllers/officing/base_controller.rb @@ -13,6 +13,12 @@ class Officing::BaseController < ApplicationController raise CanCan::AccessDenied unless current_user.try(:poll_officer?) end + def check_officer_assignment + if @officer_assignment.blank? + go_back_to_new(t("officing.results.flash.error_wrong_booth")) + end + end + def load_officer_assignment @officer_assignments ||= current_user.poll_officer. officer_assignments. diff --git a/app/controllers/officing/results_controller.rb b/app/controllers/officing/results_controller.rb index ff9bf3925..cba0d6b0b 100644 --- a/app/controllers/officing/results_controller.rb +++ b/app/controllers/officing/results_controller.rb @@ -33,12 +33,6 @@ class Officing::ResultsController < Officing::BaseController private - def check_officer_assignment - if @officer_assignment.blank? - go_back_to_new(t("officing.results.flash.error_wrong_booth")) - end - end - def build_results @results = [] diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 70f1c7030..89999ac78 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -11,8 +11,8 @@ class PollsController < ApplicationController ::Poll::Answer # trigger autoload def index - @polls = @polls.public_polls.send(@current_filter).includes(:geozones) - .sort_for_list.page(params[:page]) + @polls = @polls.not_budget.public_polls.send(@current_filter).includes(:geozones) + .sort_for_list.page(params[:page]) end def show diff --git a/app/controllers/users/confirmations_controller.rb b/app/controllers/users/confirmations_controller.rb index de65e592a..3ffced63e 100644 --- a/app/controllers/users/confirmations_controller.rb +++ b/app/controllers/users/confirmations_controller.rb @@ -27,7 +27,7 @@ class Users::ConfirmationsController < Devise::ConfirmationsController def show # In the default implementation, this already confirms the resource: # self.resource = self.resource = resource_class.confirm_by_token(params[:confirmation_token]) - self.resource = resource_class.find_by(confirmation_token: params[:confirmation_token]) + self.resource = resource_class.find_by!(confirmation_token: params[:confirmation_token]) yield resource if block_given? diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 0e0f741a3..67edc4e26 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -25,7 +25,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def sign_in_with(feature, provider) raise ActionController::RoutingError.new("Not Found") unless Setting["feature.#{feature}"] - auth = env["omniauth.auth"] + auth = request.env["omniauth.auth"] identity = Identity.first_or_create_from_oauth(auth) @user = current_user || identity.user || User.first_or_initialize_for_oauth(auth) diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index a63945342..0270b36c7 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -1,6 +1,6 @@ class Users::RegistrationsController < Devise::RegistrationsController prepend_before_action :authenticate_scope!, only: [:edit, :update, :destroy, :finish_signup, :do_finish_signup] - before_filter :configure_permitted_parameters + before_action :configure_permitted_parameters invisible_captcha only: [:create], honeypot: :address, scope: :user @@ -66,7 +66,7 @@ class Users::RegistrationsController < Devise::RegistrationsController end def configure_permitted_parameters - devise_parameter_sanitizer.for(:account_update).push(:email) + devise_parameter_sanitizer.permit(:account_update, keys: [:email]) end def erase_params diff --git a/app/controllers/valuation/budget_investments_controller.rb b/app/controllers/valuation/budget_investments_controller.rb index 2ee531f27..aa29120f1 100644 --- a/app/controllers/valuation/budget_investments_controller.rb +++ b/app/controllers/valuation/budget_investments_controller.rb @@ -61,7 +61,7 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController end def resource_name - resource_model.parameterize("_") + resource_model.parameterize(separator: "_") end def load_budget @@ -97,8 +97,8 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController end def params_for_current_valuator - Budget::Investment.filter_params(params).merge(valuator_id: current_user.valuator.id, - budget_id: @budget.id) + Budget::Investment.filter_params(params).to_h.merge({ valuator_id: current_user.valuator.id, + budget_id: @budget.id }) end def valuation_params diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 052bbd5ed..40dd1073b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -72,4 +72,8 @@ module ApplicationHelper render custom_partial_path if lookup_context.exists?(custom_partial_path, [], true) end + def management_controller? + controller.class.to_s.include?("Management") + end + end diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index df48a08fa..15fdc91a8 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -12,7 +12,8 @@ module BudgetsHelper end def csv_params - csv_params = params.clone.merge(format: :csv).symbolize_keys + csv_params = params.clone.merge(format: :csv) + csv_params = csv_params.to_unsafe_h.map { |k, v| [k.to_sym, v] }.to_h csv_params.delete(:page) csv_params end @@ -96,4 +97,16 @@ module BudgetsHelper !current_user.voted_in_group?(investment.group) && investment.group.headings.count > 1 end + + def link_to_create_budget_poll(budget) + balloting_phase = budget.phases.where(kind: "balloting").first + + link_to t("admin.budgets.index.admin_ballots"), + admin_polls_path(poll: { + name: budget.name, + budget_id: budget.id, + starts_at: balloting_phase.starts_at, + ends_at: balloting_phase.ends_at }), + method: :post + end end diff --git a/app/helpers/documentables_helper.rb b/app/helpers/documentables_helper.rb index b17278019..ef1a2d6b9 100644 --- a/app/helpers/documentables_helper.rb +++ b/app/helpers/documentables_helper.rb @@ -1,7 +1,7 @@ module DocumentablesHelper def documentable_class(documentable) - documentable.class.name.parameterize("_") + documentable.class.name.parameterize(separator: "_") end def max_documents_allowed(documentable) diff --git a/app/helpers/followables_helper.rb b/app/helpers/followables_helper.rb index 5641a33bc..bf6cbd8f6 100644 --- a/app/helpers/followables_helper.rb +++ b/app/helpers/followables_helper.rb @@ -22,7 +22,7 @@ module FollowablesHelper end def followable_class_name(followable) - followable.class.to_s.parameterize("_") + followable.class.to_s.parameterize(separator: "_") end def find_or_build_follow(user, followable) diff --git a/app/helpers/globalize_helper.rb b/app/helpers/globalize_helper.rb index 575e81c8e..92d02b63e 100644 --- a/app/helpers/globalize_helper.rb +++ b/app/helpers/globalize_helper.rb @@ -12,7 +12,7 @@ module GlobalizeHelper def display_translation?(resource, locale) if !resource || resource.translations.blank? || - resource.translations.map(&:locale).include?(I18n.locale) + resource.locales_not_marked_for_destruction.include?(I18n.locale) locale == I18n.locale else locale == resource.translations.first.locale diff --git a/app/helpers/imageables_helper.rb b/app/helpers/imageables_helper.rb index 768578f75..1a85362d8 100644 --- a/app/helpers/imageables_helper.rb +++ b/app/helpers/imageables_helper.rb @@ -5,7 +5,7 @@ module ImageablesHelper end def imageable_class(imageable) - imageable.class.name.parameterize("_") + imageable.class.name.parameterize(separator: "_") end def imageable_max_file_size diff --git a/app/helpers/translatable_form_helper.rb b/app/helpers/translatable_form_helper.rb index 01b0dd2a7..a65221b79 100644 --- a/app/helpers/translatable_form_helper.rb +++ b/app/helpers/translatable_form_helper.rb @@ -6,7 +6,13 @@ module TranslatableFormHelper end class TranslatableFormBuilder < FoundationRailsHelper::FormBuilder + attr_accessor :translations + def translatable_fields(&block) + @translations = {} + @object.globalize_locales.map do |locale| + @translations[locale] = translation_for(locale) + end @object.globalize_locales.map do |locale| Globalize.with_locale(locale) { fields_for_locale(locale, &block) } end.join.html_safe @@ -15,7 +21,7 @@ module TranslatableFormHelper private def fields_for_locale(locale, &block) - fields_for_translation(translation_for(locale)) do |translations_form| + fields_for_translation(@translations[locale]) do |translations_form| @template.content_tag :div, translations_options(translations_form.object, locale) do @template.concat translations_form.hidden_field( :_destroy, diff --git a/app/models/active_poll.rb b/app/models/active_poll.rb index 50e185ea5..040a33451 100644 --- a/app/models/active_poll.rb +++ b/app/models/active_poll.rb @@ -1,4 +1,4 @@ -class ActivePoll < ActiveRecord::Base +class ActivePoll < ApplicationRecord include Measurable translates :description, touch: true diff --git a/app/models/activity.rb b/app/models/activity.rb index b5f3e0281..ed617c97a 100644 --- a/app/models/activity.rb +++ b/app/models/activity.rb @@ -1,4 +1,4 @@ -class Activity < ActiveRecord::Base +class Activity < ApplicationRecord belongs_to :actionable, -> { with_hidden }, polymorphic: true belongs_to :user, -> { with_hidden } diff --git a/app/models/admin_notification.rb b/app/models/admin_notification.rb index 6fc3e83e3..5e86f3d28 100644 --- a/app/models/admin_notification.rb +++ b/app/models/admin_notification.rb @@ -1,4 +1,4 @@ -class AdminNotification < ActiveRecord::Base +class AdminNotification < ApplicationRecord include Notifiable translates :title, touch: true diff --git a/app/models/administrator.rb b/app/models/administrator.rb index 6cfafe8d9..b8b6cc1c0 100644 --- a/app/models/administrator.rb +++ b/app/models/administrator.rb @@ -1,4 +1,4 @@ -class Administrator < ActiveRecord::Base +class Administrator < ApplicationRecord belongs_to :user, touch: true delegate :name, :email, :name_and_email, to: :user diff --git a/app/models/ahoy/event.rb b/app/models/ahoy/event.rb index 2aac3c59c..ec7e9c57e 100644 --- a/app/models/ahoy/event.rb +++ b/app/models/ahoy/event.rb @@ -1,5 +1,5 @@ module Ahoy - class Event < ActiveRecord::Base + class Event < ApplicationRecord self.table_name = "ahoy_events" belongs_to :visit diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 000000000..10a4cba84 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/models/banner.rb b/app/models/banner.rb index cc05b3970..9b8ce7b3c 100644 --- a/app/models/banner.rb +++ b/app/models/banner.rb @@ -1,4 +1,4 @@ -class Banner < ActiveRecord::Base +class Banner < ApplicationRecord acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases diff --git a/app/models/banner/section.rb b/app/models/banner/section.rb index 493093731..5a09aaf36 100644 --- a/app/models/banner/section.rb +++ b/app/models/banner/section.rb @@ -1,4 +1,4 @@ -class Banner::Section < ActiveRecord::Base +class Banner::Section < ApplicationRecord belongs_to :banner belongs_to :web_section end diff --git a/app/models/budget.rb b/app/models/budget.rb index ecfacc5c0..8c34e030d 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -1,4 +1,4 @@ -class Budget < ActiveRecord::Base +class Budget < ApplicationRecord include Measurable include Sluggable @@ -6,6 +6,18 @@ class Budget < ActiveRecord::Base translates :name, touch: true include Globalizable + class Translation + validate :name_uniqueness_by_budget + + def name_uniqueness_by_budget + if Budget.joins(:translations) + .where(name: name) + .where.not("budget_translations.budget_id": budget_id).any? + errors.add(:name, I18n.t("errors.messages.taken")) + end + end + end + CURRENCY_SYMBOLS = %w(€ $ £ ¥).freeze before_validation :assign_model_to_translations @@ -21,6 +33,8 @@ class Budget < ActiveRecord::Base has_many :headings, through: :groups has_many :phases, class_name: Budget::Phase + has_one :poll + before_validation :sanitize_descriptions after_create :generate_phases diff --git a/app/models/budget/ballot.rb b/app/models/budget/ballot.rb index c35222f3a..9539119b0 100644 --- a/app/models/budget/ballot.rb +++ b/app/models/budget/ballot.rb @@ -1,12 +1,13 @@ class Budget - class Ballot < ActiveRecord::Base + class Ballot < ApplicationRecord belongs_to :user belongs_to :budget + belongs_to :poll_ballot, class_name: "Poll::Ballot" has_many :lines, dependent: :destroy has_many :investments, through: :lines - has_many :groups, -> { uniq }, through: :lines - has_many :headings, -> { uniq }, through: :groups + has_many :groups, -> { distinct }, through: :lines + has_many :headings, -> { distinct }, through: :groups def add_investment(investment) lines.create(investment: investment).persisted? @@ -70,5 +71,9 @@ class Budget investments.where(group: group).first.heading end + def casted_offline? + budget.poll&.voted_by?(user) + end + end end diff --git a/app/models/budget/ballot/line.rb b/app/models/budget/ballot/line.rb index a3c24b631..54b26f4b4 100644 --- a/app/models/budget/ballot/line.rb +++ b/app/models/budget/ballot/line.rb @@ -1,6 +1,6 @@ class Budget class Ballot - class Line < ActiveRecord::Base + class Line < ApplicationRecord belongs_to :ballot belongs_to :investment, counter_cache: :ballot_lines_count belongs_to :heading @@ -16,6 +16,7 @@ class Budget scope :by_investment, ->(investment_id) { where(investment_id: investment_id) } before_validation :set_denormalized_ids + after_save :store_user_heading def check_sufficient_funds errors.add(:money, "insufficient funds") if ballot.amount_available(investment.heading) < investment.price.to_i @@ -37,6 +38,10 @@ class Budget self.group_id ||= investment.try(:group_id) self.budget_id ||= investment.try(:budget_id) end + + def store_user_heading + ballot.user.update(balloted_heading_id: heading.id) unless ballot.physical == true + end end end end diff --git a/app/models/budget/content_block.rb b/app/models/budget/content_block.rb index bba830cec..ae3bf44e9 100644 --- a/app/models/budget/content_block.rb +++ b/app/models/budget/content_block.rb @@ -1,5 +1,5 @@ class Budget - class ContentBlock < ActiveRecord::Base + class ContentBlock < ApplicationRecord validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) } validates :heading, presence: true validates_uniqueness_of :heading, scope: :locale diff --git a/app/models/budget/group.rb b/app/models/budget/group.rb index 37d6e658b..d77c840c0 100644 --- a/app/models/budget/group.rb +++ b/app/models/budget/group.rb @@ -1,9 +1,22 @@ class Budget - class Group < ActiveRecord::Base + class Group < ApplicationRecord include Sluggable translates :name, touch: true include Globalizable + translation_class_delegate :budget + + class Translation + validate :name_uniqueness_by_budget + + def name_uniqueness_by_budget + if budget.groups.joins(:translations) + .where(name: name) + .where.not("budget_group_translations.budget_group_id": budget_group_id).any? + errors.add(:name, I18n.t("errors.messages.taken")) + end + end + end belongs_to :budget @@ -15,7 +28,7 @@ class Budget validates :budget_id, presence: true validates :slug, presence: true, format: /\A[a-z0-9\-_]+\z/ - scope :sort_by_name, -> { includes(:translations).order(:name) } + scope :sort_by_name, -> { joins(:translations).order(:name) } def single_heading_group? headings.count == 1 diff --git a/app/models/budget/group/translation.rb b/app/models/budget/group/translation.rb deleted file mode 100644 index 36489eb10..000000000 --- a/app/models/budget/group/translation.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Budget::Group::Translation < Globalize::ActiveRecord::Translation - delegate :budget, to: :globalized_model - - validate :name_uniqueness_by_budget - - def name_uniqueness_by_budget - if budget.groups.joins(:translations) - .where(name: name) - .where.not("budget_group_translations.budget_group_id": budget_group_id).any? - errors.add(:name, I18n.t("errors.messages.taken")) - end - end -end diff --git a/app/models/budget/heading.rb b/app/models/budget/heading.rb index ac9ac6492..0b94aac67 100644 --- a/app/models/budget/heading.rb +++ b/app/models/budget/heading.rb @@ -1,11 +1,25 @@ class Budget - class Heading < ActiveRecord::Base + class Heading < ApplicationRecord OSM_DISTRICT_LEVEL_ZOOM = 12.freeze include Sluggable translates :name, touch: true include Globalizable + translation_class_delegate :budget + + class Translation + validate :name_uniqueness_by_budget + + def name_uniqueness_by_budget + if budget.headings + .joins(:translations) + .where(name: name) + .where.not("budget_heading_translations.budget_heading_id": budget_heading_id).any? + errors.add(:name, I18n.t("errors.messages.taken")) + end + end + end belongs_to :group @@ -26,8 +40,8 @@ class Budget delegate :budget, :budget_id, to: :group, allow_nil: true - scope :i18n, -> { includes(:translations) } - scope :allow_custom_content, -> { i18n.where(allow_custom_content: true).order(:name) } + scope :i18n, -> { joins(:translations) } + scope :allow_custom_content, -> { i18n.where(allow_custom_content: true).order("budget_heading_translations.name") } def self.sort_by_name all.sort do |heading, other_heading| diff --git a/app/models/budget/heading/translation.rb b/app/models/budget/heading/translation.rb deleted file mode 100644 index 3cf930f66..000000000 --- a/app/models/budget/heading/translation.rb +++ /dev/null @@ -1,14 +0,0 @@ -class Budget::Heading::Translation < Globalize::ActiveRecord::Translation - delegate :budget, to: :globalized_model - - validate :name_uniqueness_by_budget - - def name_uniqueness_by_budget - if budget.headings - .joins(:translations) - .where(name: name) - .where.not("budget_heading_translations.budget_heading_id": budget_heading_id).any? - errors.add(:name, I18n.t("errors.messages.taken")) - end - end -end diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index b033d7404..2eaf801c1 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -1,5 +1,5 @@ class Budget - class Investment < ActiveRecord::Base + class Investment < ApplicationRecord SORTING_OPTIONS = {id: "id", title: "title", supports: "cached_votes_up"}.freeze include Rails.application.routes.url_helpers @@ -109,7 +109,7 @@ class Budget end def self.filter_params(params) - params.select{ |x, _| %w{heading_id group_id administrator_id tag_name valuator_id}.include?(x.to_s) } + params.permit(%i[heading_id group_id administrator_id tag_name valuator_id]) end def self.scoped_filter(params, current_filter) @@ -248,6 +248,7 @@ class Budget return :no_ballots_allowed unless budget.balloting? return :different_heading_assigned_html unless ballot.valid_heading?(heading) return :not_enough_money_html if ballot.present? && !enough_money?(ballot) + return :casted_offline if ballot.casted_offline? end def permission_problem(user) @@ -367,7 +368,7 @@ class Budget end def self.with_milestone_status_id(status_id) - joins(:milestones).includes(:milestones).select do |investment| + includes(milestones: :translations).select do |investment| investment.milestone_status_id == status_id.to_i end end diff --git a/app/models/budget/phase.rb b/app/models/budget/phase.rb index cd877e0cc..5912a1453 100644 --- a/app/models/budget/phase.rb +++ b/app/models/budget/phase.rb @@ -1,5 +1,5 @@ class Budget - class Phase < ActiveRecord::Base + class Phase < ApplicationRecord PHASE_KINDS = %w(drafting informing accepting reviewing selecting valuating publishing_prices balloting reviewing_ballots finished).freeze PUBLISHED_PRICES_PHASES = %w(publishing_prices balloting reviewing_ballots finished).freeze @@ -9,6 +9,7 @@ class Budget translates :summary, touch: true translates :description, touch: true include Globalizable + include Sanitizable belongs_to :budget belongs_to :next_phase, class_name: "Budget::Phase", foreign_key: :next_phase_id diff --git a/app/models/budget/phase/translation.rb b/app/models/budget/phase/translation.rb deleted file mode 100644 index 53390143a..000000000 --- a/app/models/budget/phase/translation.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Budget::Phase::Translation < Globalize::ActiveRecord::Translation - before_validation :sanitize_description - - private - - def sanitize_description - self.description = WYSIWYGSanitizer.new.sanitize(description) - end -end diff --git a/app/models/budget/reclassified_vote.rb b/app/models/budget/reclassified_vote.rb index 0eb44d8cc..3f11aa388 100644 --- a/app/models/budget/reclassified_vote.rb +++ b/app/models/budget/reclassified_vote.rb @@ -1,5 +1,5 @@ class Budget - class ReclassifiedVote < ActiveRecord::Base + class ReclassifiedVote < ApplicationRecord REASONS = %w(heading_changed unfeasible) belongs_to :user diff --git a/app/models/budget/translation.rb b/app/models/budget/translation.rb deleted file mode 100644 index 1f3d93ea1..000000000 --- a/app/models/budget/translation.rb +++ /dev/null @@ -1,11 +0,0 @@ -class Budget::Translation < Globalize::ActiveRecord::Translation - validate :name_uniqueness_by_budget - - def name_uniqueness_by_budget - if Budget.joins(:translations) - .where(name: name) - .where.not("budget_translations.budget_id": budget_id).any? - errors.add(:name, I18n.t("errors.messages.taken")) - end - end -end diff --git a/app/models/budget/valuator_assignment.rb b/app/models/budget/valuator_assignment.rb index 18ef73812..9f60caf1e 100644 --- a/app/models/budget/valuator_assignment.rb +++ b/app/models/budget/valuator_assignment.rb @@ -1,5 +1,5 @@ class Budget - class ValuatorAssignment < ActiveRecord::Base + class ValuatorAssignment < ApplicationRecord belongs_to :valuator, counter_cache: :budget_investments_count belongs_to :investment, counter_cache: true end diff --git a/app/models/budget/valuator_group_assignment.rb b/app/models/budget/valuator_group_assignment.rb index 88a04ae1a..3aa93cb14 100644 --- a/app/models/budget/valuator_group_assignment.rb +++ b/app/models/budget/valuator_group_assignment.rb @@ -1,5 +1,5 @@ class Budget - class ValuatorGroupAssignment < ActiveRecord::Base + class ValuatorGroupAssignment < ApplicationRecord belongs_to :valuator_group, counter_cache: :budget_investments_count belongs_to :investment, counter_cache: true end diff --git a/app/models/campaign.rb b/app/models/campaign.rb index 3ce027734..69ab7c811 100644 --- a/app/models/campaign.rb +++ b/app/models/campaign.rb @@ -1,2 +1,2 @@ -class Campaign < ActiveRecord::Base +class Campaign < ApplicationRecord end diff --git a/app/models/ckeditor/asset.rb b/app/models/ckeditor/asset.rb index cf636ed19..5c166fdfc 100644 --- a/app/models/ckeditor/asset.rb +++ b/app/models/ckeditor/asset.rb @@ -1,4 +1,4 @@ -class Ckeditor::Asset < ActiveRecord::Base +class Ckeditor::Asset < ApplicationRecord include Ckeditor::Orm::ActiveRecord::AssetBase include Ckeditor::Backend::Paperclip end diff --git a/app/models/comment.rb b/app/models/comment.rb index f940a5b3c..76e314c23 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,4 +1,4 @@ -class Comment < ActiveRecord::Base +class Comment < ApplicationRecord include Flaggable include HasPublicAuthor include Graphqlable @@ -22,7 +22,7 @@ class Comment < ActiveRecord::Base validate :validate_body_length validate :comment_valuation, if: -> { valuation } - belongs_to :commentable, -> { with_hidden }, polymorphic: true, counter_cache: true + belongs_to :commentable, -> { with_hidden }, polymorphic: true, counter_cache: true, touch: true belongs_to :user, -> { with_hidden } before_save :calculate_confidence_score diff --git a/app/models/community.rb b/app/models/community.rb index 78bc2994f..776f0b47d 100644 --- a/app/models/community.rb +++ b/app/models/community.rb @@ -1,4 +1,4 @@ -class Community < ActiveRecord::Base +class Community < ApplicationRecord has_one :proposal has_one :investment, class_name: Budget::Investment has_many :topics diff --git a/app/models/concerns/galleryable.rb b/app/models/concerns/galleryable.rb index 1063c5571..5ddf322f6 100644 --- a/app/models/concerns/galleryable.rb +++ b/app/models/concerns/galleryable.rb @@ -6,7 +6,7 @@ module Galleryable accepts_nested_attributes_for :images, allow_destroy: true, update_only: true def image_url(style) - image.attachment.url(style) if image && image.attachment.exists? + image&.attachment&.url(style) || "" end end -end \ No newline at end of file +end diff --git a/app/models/concerns/globalizable.rb b/app/models/concerns/globalizable.rb index e8772f19c..f963787c7 100644 --- a/app/models/concerns/globalizable.rb +++ b/app/models/concerns/globalizable.rb @@ -12,6 +12,10 @@ module Globalizable def assign_model_to_translations translations.each { |translation| translation.globalized_model = self } end + + def description + self.read_attribute(:description).try :html_safe + end end class_methods do @@ -19,5 +23,9 @@ module Globalizable validates(method, options.merge(if: lambda { |resource| resource.translations.blank? })) translation_class.instance_eval { validates method, options } end + + def translation_class_delegate(method) + translation_class.instance_eval { delegate method, to: :globalized_model } + end end end diff --git a/app/models/concerns/imageable.rb b/app/models/concerns/imageable.rb index 727ff9a6b..3e3b15685 100644 --- a/app/models/concerns/imageable.rb +++ b/app/models/concerns/imageable.rb @@ -6,7 +6,7 @@ module Imageable accepts_nested_attributes_for :image, allow_destroy: true, update_only: true def image_url(style) - image.attachment.url(style) if image && image.attachment.exists? + image&.attachment&.url(style) || "" end end end diff --git a/app/models/concerns/randomizable.rb b/app/models/concerns/randomizable.rb index c346f1f02..98a86b426 100644 --- a/app/models/concerns/randomizable.rb +++ b/app/models/concerns/randomizable.rb @@ -3,7 +3,7 @@ module Randomizable class_methods do def sort_by_random(seed = rand(10_000_000)) - ids = pluck(:id).shuffle(random: Random.new(seed)) + ids = order(:id).pluck(:id).shuffle(random: Random.new(seed)) return all if ids.empty? diff --git a/app/models/concerns/sanitizable.rb b/app/models/concerns/sanitizable.rb index 055859c8b..8602257ef 100644 --- a/app/models/concerns/sanitizable.rb +++ b/app/models/concerns/sanitizable.rb @@ -4,20 +4,47 @@ module Sanitizable included do before_validation :sanitize_description before_validation :sanitize_tag_list - end - def description - super.try :html_safe + unless included_modules.include? Globalizable + def description + super.try :html_safe + end + end end protected def sanitize_description - self.description = WYSIWYGSanitizer.new.sanitize(description) + if translatable_description? + sanitize_description_translations + else + self.description = WYSIWYGSanitizer.new.sanitize(description) + end end def sanitize_tag_list self.tag_list = TagSanitizer.new.sanitize_tag_list(tag_list) if self.class.taggable? end + def translatable_description? + self.class.included_modules.include?(Globalizable) && + self.class.translated_attribute_names.include?(:description) + end + + def sanitize_description_translations + # Sanitize description when using attribute accessor in place of nested translations. + # This is because Globalize gem create translations on after save callback + # https://github.com/globalize/globalize/blob/e37c471775d196cd4318e61954572c300c015467/lib/globalize/active_record/act_macro.rb#L105 + if translations.empty? + Globalize.with_locale(I18n.locale) do + self.description = WYSIWYGSanitizer.new.sanitize(description) + end + end + + translations.reject(&:_destroy).each do |translation| + Globalize.with_locale(translation.locale) do + self.description = WYSIWYGSanitizer.new.sanitize(description) + end + end + end end diff --git a/app/models/debate.rb b/app/models/debate.rb index e3b1aad68..fa4130038 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -1,5 +1,5 @@ require "numeric" -class Debate < ActiveRecord::Base +class Debate < ApplicationRecord include Rails.application.routes.url_helpers include Flaggable include Taggable diff --git a/app/models/direct_message.rb b/app/models/direct_message.rb index b4907ae7a..4f3b08482 100644 --- a/app/models/direct_message.rb +++ b/app/models/direct_message.rb @@ -1,4 +1,4 @@ -class DirectMessage < ActiveRecord::Base +class DirectMessage < ApplicationRecord belongs_to :sender, class_name: "User", foreign_key: "sender_id" belongs_to :receiver, class_name: "User", foreign_key: "receiver_id" diff --git a/app/models/direct_upload.rb b/app/models/direct_upload.rb index c4d1456e7..088c8ea64 100644 --- a/app/models/direct_upload.rb +++ b/app/models/direct_upload.rb @@ -51,7 +51,7 @@ class DirectUpload @relation.valid? if @relation.errors.key? :attachment - errors[:attachment] = @relation.errors[:attachment] + errors.add(:attachment, @relation.errors.full_messages_for(:attachment)) end end diff --git a/app/models/document.rb b/app/models/document.rb index 108f29fad..3a78231f1 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -1,4 +1,4 @@ -class Document < ActiveRecord::Base +class Document < ApplicationRecord include DocumentsHelper include DocumentablesHelper has_attached_file :attachment, url: "/system/:class/:prefix/:style/:hash.:extension", @@ -80,24 +80,26 @@ class Document < ActiveRecord::Base def validate_attachment_size if documentable_class.present? && attachment_file_size > documentable_class.max_file_size - errors[:attachment] = I18n.t("documents.errors.messages.in_between", + errors.add(:attachment, I18n.t("documents.errors.messages.in_between", min: "0 Bytes", - max: "#{max_file_size(documentable_class)} MB") + max: "#{max_file_size(documentable_class)} MB")) end end def validate_attachment_content_type if documentable_class && !accepted_content_types(documentable_class).include?(attachment_content_type) - errors[:attachment] = I18n.t("documents.errors.messages.wrong_content_type", - content_type: attachment_content_type, - accepted_content_types: documentable_humanized_accepted_content_types(documentable_class)) + accepted_content_types = documentable_humanized_accepted_content_types(documentable_class) + message = I18n.t("documents.errors.messages.wrong_content_type", + content_type: attachment_content_type, + accepted_content_types: accepted_content_types) + errors.add(:attachment, message) end end def attachment_presence if attachment.blank? && cached_attachment.blank? - errors[:attachment] = I18n.t("errors.messages.blank") + errors.add(:attachment, I18n.t("errors.messages.blank")) end end diff --git a/app/models/failed_census_call.rb b/app/models/failed_census_call.rb index c0add2070..7b3c994d8 100644 --- a/app/models/failed_census_call.rb +++ b/app/models/failed_census_call.rb @@ -1,4 +1,4 @@ -class FailedCensusCall < ActiveRecord::Base +class FailedCensusCall < ApplicationRecord belongs_to :user, counter_cache: true belongs_to :poll_officer, class_name: "Poll::Officer", counter_cache: true end diff --git a/app/models/flag.rb b/app/models/flag.rb index a05d8a737..e69393d49 100644 --- a/app/models/flag.rb +++ b/app/models/flag.rb @@ -1,4 +1,4 @@ -class Flag < ActiveRecord::Base +class Flag < ApplicationRecord belongs_to :user belongs_to :flaggable, polymorphic: true, counter_cache: true, touch: true diff --git a/app/models/follow.rb b/app/models/follow.rb index 51628f7d4..8062ffecc 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -1,4 +1,4 @@ -class Follow < ActiveRecord::Base +class Follow < ApplicationRecord belongs_to :user belongs_to :followable, polymorphic: true diff --git a/app/models/geozone.rb b/app/models/geozone.rb index 7cdcbab27..f32af5ec6 100644 --- a/app/models/geozone.rb +++ b/app/models/geozone.rb @@ -1,4 +1,4 @@ -class Geozone < ActiveRecord::Base +class Geozone < ApplicationRecord include Graphqlable diff --git a/app/models/i18n_content.rb b/app/models/i18n_content.rb index 81c4ebee7..173c7310a 100644 --- a/app/models/i18n_content.rb +++ b/app/models/i18n_content.rb @@ -1,4 +1,4 @@ -class I18nContent < ActiveRecord::Base +class I18nContent < ApplicationRecord scope :by_key, ->(key) { where(key: key) } scope :begins_with_key, ->(key) { where("key ILIKE ?", "#{key}%") } diff --git a/app/models/i18n_content_translation.rb b/app/models/i18n_content_translation.rb index 76447d83e..4e754a3a5 100644 --- a/app/models/i18n_content_translation.rb +++ b/app/models/i18n_content_translation.rb @@ -1,5 +1,5 @@ -class I18nContentTranslation < ActiveRecord::Base +class I18nContentTranslation < ApplicationRecord def self.existing_languages - self.select(:locale).uniq.map{ |l| l.locale.to_sym }.to_a + self.select(:locale).distinct.map { |l| l.locale.to_sym }.to_a end end diff --git a/app/models/identity.rb b/app/models/identity.rb index e3704da01..311ac61e4 100644 --- a/app/models/identity.rb +++ b/app/models/identity.rb @@ -1,4 +1,4 @@ -class Identity < ActiveRecord::Base +class Identity < ApplicationRecord belongs_to :user validates :provider, presence: true diff --git a/app/models/image.rb b/app/models/image.rb index 8f62f94d8..eefcd3926 100644 --- a/app/models/image.rb +++ b/app/models/image.rb @@ -1,4 +1,4 @@ -class Image < ActiveRecord::Base +class Image < ApplicationRecord include ImagesHelper include ImageablesHelper @@ -79,23 +79,24 @@ class Image < ActiveRecord::Base def validate_attachment_size if imageable_class && attachment_file_size > 1.megabytes - errors[:attachment] = I18n.t("images.errors.messages.in_between", - min: "0 Bytes", - max: "#{imageable_max_file_size} MB") + errors.add(:attachment, I18n.t("images.errors.messages.in_between", + min: "0 Bytes", + max: "#{imageable_max_file_size} MB")) end end def validate_attachment_content_type if imageable_class && !attachment_of_valid_content_type? - errors[:attachment] = I18n.t("images.errors.messages.wrong_content_type", - content_type: attachment_content_type, - accepted_content_types: imageable_humanized_accepted_content_types) + message = I18n.t("images.errors.messages.wrong_content_type", + content_type: attachment_content_type, + accepted_content_types: imageable_humanized_accepted_content_types) + errors.add(:attachment, message) end end def attachment_presence if attachment.blank? && cached_attachment.blank? - errors[:attachment] = I18n.t("errors.messages.blank") + errors.add(:attachment, I18n.t("errors.messages.blank")) end end diff --git a/app/models/legislation/annotation.rb b/app/models/legislation/annotation.rb index 5cb190cc2..93a6c1acf 100644 --- a/app/models/legislation/annotation.rb +++ b/app/models/legislation/annotation.rb @@ -1,4 +1,4 @@ -class Legislation::Annotation < ActiveRecord::Base +class Legislation::Annotation < ApplicationRecord COMMENTS_PAGE_SIZE = 5 acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases diff --git a/app/models/legislation/answer.rb b/app/models/legislation/answer.rb index 298fe9f6d..3bf052167 100644 --- a/app/models/legislation/answer.rb +++ b/app/models/legislation/answer.rb @@ -1,4 +1,4 @@ -class Legislation::Answer < ActiveRecord::Base +class Legislation::Answer < ApplicationRecord acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases diff --git a/app/models/legislation/draft_version.rb b/app/models/legislation/draft_version.rb index 99dafac76..57f1039a4 100644 --- a/app/models/legislation/draft_version.rb +++ b/app/models/legislation/draft_version.rb @@ -1,4 +1,4 @@ -class Legislation::DraftVersion < ActiveRecord::Base +class Legislation::DraftVersion < ApplicationRecord VALID_STATUSES = %w(draft published) acts_as_paranoid column: :hidden_at diff --git a/app/models/legislation/process.rb b/app/models/legislation/process.rb index 46d879b63..3d2c72c27 100644 --- a/app/models/legislation/process.rb +++ b/app/models/legislation/process.rb @@ -1,4 +1,4 @@ -class Legislation::Process < ActiveRecord::Base +class Legislation::Process < ApplicationRecord include ActsAsParanoidAliases include Taggable include Milestoneable diff --git a/app/models/legislation/proposal.rb b/app/models/legislation/proposal.rb index 0e1a39c90..16ab2d7dd 100644 --- a/app/models/legislation/proposal.rb +++ b/app/models/legislation/proposal.rb @@ -1,4 +1,4 @@ -class Legislation::Proposal < ActiveRecord::Base +class Legislation::Proposal < ApplicationRecord include ActsAsParanoidAliases include Flaggable include Taggable diff --git a/app/models/legislation/question.rb b/app/models/legislation/question.rb index acee09088..6c60eb9f3 100644 --- a/app/models/legislation/question.rb +++ b/app/models/legislation/question.rb @@ -1,4 +1,4 @@ -class Legislation::Question < ActiveRecord::Base +class Legislation::Question < ApplicationRecord acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases include Notifiable diff --git a/app/models/legislation/question_option.rb b/app/models/legislation/question_option.rb index f69c60894..c6f846120 100644 --- a/app/models/legislation/question_option.rb +++ b/app/models/legislation/question_option.rb @@ -1,4 +1,4 @@ -class Legislation::QuestionOption < ActiveRecord::Base +class Legislation::QuestionOption < ApplicationRecord acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases diff --git a/app/models/local_census_record.rb b/app/models/local_census_record.rb index 1c2c42d44..d275ec130 100644 --- a/app/models/local_census_record.rb +++ b/app/models/local_census_record.rb @@ -1,4 +1,4 @@ -class LocalCensusRecord < ActiveRecord::Base +class LocalCensusRecord < ApplicationRecord validates :document_number, presence: true validates :document_type, presence: true validates :date_of_birth, presence: true diff --git a/app/models/lock.rb b/app/models/lock.rb index c0d5fae39..bcfa41196 100644 --- a/app/models/lock.rb +++ b/app/models/lock.rb @@ -1,4 +1,4 @@ -class Lock < ActiveRecord::Base +class Lock < ApplicationRecord belongs_to :user before_save :set_locked_until @@ -21,7 +21,7 @@ class Lock < ActiveRecord::Base end def self.increase_tries(user) - Lock.find_or_create_by(user: user).increment!(:tries) + Lock.find_or_create_by(user: user).increment!(:tries).save end def self.max_tries diff --git a/app/models/manager.rb b/app/models/manager.rb index d9c1aff07..c0e2987e0 100644 --- a/app/models/manager.rb +++ b/app/models/manager.rb @@ -1,4 +1,4 @@ -class Manager < ActiveRecord::Base +class Manager < ApplicationRecord belongs_to :user, touch: true delegate :name, :email, :name_and_email, to: :user diff --git a/app/models/map_location.rb b/app/models/map_location.rb index 892ba8f20..d69c97ea3 100644 --- a/app/models/map_location.rb +++ b/app/models/map_location.rb @@ -1,4 +1,4 @@ -class MapLocation < ActiveRecord::Base +class MapLocation < ApplicationRecord belongs_to :proposal, touch: true belongs_to :investment, class_name: Budget::Investment, touch: true diff --git a/app/models/milestone.rb b/app/models/milestone.rb index d4ef41137..69d46149a 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -1,4 +1,4 @@ -class Milestone < ActiveRecord::Base +class Milestone < ApplicationRecord include Imageable include Documentable documentable max_documents_allowed: 3, @@ -7,6 +7,7 @@ class Milestone < ActiveRecord::Base translates :title, :description, touch: true include Globalizable + translation_class_delegate :status_id belongs_to :milestoneable, polymorphic: true belongs_to :status diff --git a/app/models/milestone/status.rb b/app/models/milestone/status.rb index 51b03427d..5f99cac22 100644 --- a/app/models/milestone/status.rb +++ b/app/models/milestone/status.rb @@ -1,4 +1,4 @@ -class Milestone::Status < ActiveRecord::Base +class Milestone::Status < ApplicationRecord acts_as_paranoid column: :hidden_at has_many :milestones diff --git a/app/models/milestone/translation.rb b/app/models/milestone/translation.rb deleted file mode 100644 index e1b589d96..000000000 --- a/app/models/milestone/translation.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Milestone::Translation < Globalize::ActiveRecord::Translation - delegate :status_id, to: :globalized_model -end diff --git a/app/models/moderator.rb b/app/models/moderator.rb index 6a5af7a52..6871f4cc5 100644 --- a/app/models/moderator.rb +++ b/app/models/moderator.rb @@ -1,4 +1,4 @@ -class Moderator < ActiveRecord::Base +class Moderator < ApplicationRecord belongs_to :user, touch: true delegate :name, :email, to: :user diff --git a/app/models/newsletter.rb b/app/models/newsletter.rb index 35ed57b91..bac4d8ef7 100644 --- a/app/models/newsletter.rb +++ b/app/models/newsletter.rb @@ -1,4 +1,4 @@ -class Newsletter < ActiveRecord::Base +class Newsletter < ApplicationRecord has_many :activities, as: :actionable validates :subject, presence: true diff --git a/app/models/notification.rb b/app/models/notification.rb index f99cbc1ca..738e5ab5f 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,4 +1,4 @@ -class Notification < ActiveRecord::Base +class Notification < ApplicationRecord belongs_to :user, counter_cache: true belongs_to :notifiable, polymorphic: true diff --git a/app/models/organization.rb b/app/models/organization.rb index 0c7aa92e9..2b9be5071 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -1,4 +1,4 @@ -class Organization < ActiveRecord::Base +class Organization < ApplicationRecord include Graphqlable diff --git a/app/models/poll.rb b/app/models/poll.rb index 95609edd6..b4e69a7bc 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -1,4 +1,4 @@ -class Poll < ActiveRecord::Base +class Poll < ApplicationRecord include Imageable acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases @@ -20,10 +20,12 @@ class Poll < ActiveRecord::Base has_many :officers, through: :officer_assignments has_many :questions, inverse_of: :poll has_many :comments, as: :commentable + has_many :ballot_sheets has_and_belongs_to_many :geozones belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id" belongs_to :related, polymorphic: true + belongs_to :budget validates_translation :name, presence: true validate :date_range @@ -39,7 +41,9 @@ class Poll < ActiveRecord::Base scope :published, -> { where("published = ?", true) } scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } scope :public_for_api, -> { all } - scope :sort_for_list, -> { order(:geozone_restricted, :starts_at, :name) } + scope :not_budget, -> { where(budget_id: nil) } + + scope :sort_for_list, -> { joins(:translations).order(:geozone_restricted, :starts_at, "poll_translations.name") } def self.overlaping_with(poll) where("? < ends_at and ? >= starts_at", poll.starts_at.beginning_of_day, @@ -82,10 +86,15 @@ class Poll < ActiveRecord::Base end def votable_by?(user) + return false if user_has_an_online_ballot(user) answerable_by?(user) && not_voted_by?(user) end + def user_has_an_online_ballot(user) + budget.present? && budget.ballots.find_by(user: user)&.lines.present? + end + def self.not_voted_by(user) where("polls.id not in (?)", poll_ids_voted_by(user)) end @@ -132,4 +141,8 @@ class Poll < ActiveRecord::Base def answer_count Poll::Answer.where(question: questions).count end + + def budget_poll? + budget.present? + end end diff --git a/app/models/poll/answer.rb b/app/models/poll/answer.rb index 8e92988ad..1e602086b 100644 --- a/app/models/poll/answer.rb +++ b/app/models/poll/answer.rb @@ -1,4 +1,4 @@ -class Poll::Answer < ActiveRecord::Base +class Poll::Answer < ApplicationRecord belongs_to :question, -> { with_hidden } belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id" diff --git a/app/models/poll/ballot.rb b/app/models/poll/ballot.rb new file mode 100644 index 000000000..0a8a55d85 --- /dev/null +++ b/app/models/poll/ballot.rb @@ -0,0 +1,36 @@ +class Poll::Ballot < ActiveRecord::Base + belongs_to :ballot_sheet, class_name: Poll::BallotSheet + + validates :ballot_sheet_id, presence: true + + def verify + investments.each do |investment_id| + add_investment(investment_id) + end + end + + def add_investment(investment_id) + investment = find_investment(investment_id) + + if investment.present? && not_already_added?(investment) + ballot.add_investment(investment) + end + end + + def investments + data.split(",") + end + + def ballot + Budget::Ballot.where(poll_ballot: self).first + end + + def find_investment(investment_id) + ballot.budget.investments.where(id: investment_id).first + end + + def not_already_added?(investment) + ballot.lines.where(investment: investment).blank? + end + +end diff --git a/app/models/poll/ballot_sheet.rb b/app/models/poll/ballot_sheet.rb new file mode 100644 index 000000000..883cb004b --- /dev/null +++ b/app/models/poll/ballot_sheet.rb @@ -0,0 +1,42 @@ +class Poll::BallotSheet < ActiveRecord::Base + belongs_to :poll + belongs_to :officer_assignment + has_many :ballots, class_name: Poll::Ballot + + validates :data, presence: true + validates :poll_id, presence: true + validates :officer_assignment_id, presence: true + + def author + officer_assignment.officer.name + end + + def verify_ballots + parsed_ballots.each_with_index do |investment_ids, index| + ballot = create_ballots(investment_ids, index) + ballot.verify + end + end + + def parsed_ballots + data.split(/[;\n]/) + end + + private + + def create_ballots(investment_ids, index) + poll_ballot = Poll::Ballot.where(ballot_sheet: self, + data: investment_ids, + external_id: index).first_or_create + create_ballot(poll_ballot) + poll_ballot + end + + def create_ballot(poll_ballot) + Budget::Ballot.where(physical: true, + user: nil, + poll_ballot: poll_ballot, + budget: poll.budget).first_or_create + end + +end diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb index e794a0190..d10270064 100644 --- a/app/models/poll/booth.rb +++ b/app/models/poll/booth.rb @@ -1,5 +1,5 @@ class Poll - class Booth < ActiveRecord::Base + class Booth < ApplicationRecord has_many :booth_assignments, class_name: "Poll::BoothAssignment" has_many :polls, through: :booth_assignments has_many :shifts @@ -12,7 +12,7 @@ class Poll end def self.available - where(polls: { id: Poll.current_or_recounting }).includes(:polls) + where(polls: { id: Poll.current_or_recounting }).joins(polls: :translations) end def assignment_on_poll(poll) diff --git a/app/models/poll/booth_assignment.rb b/app/models/poll/booth_assignment.rb index 811b98923..fa037ed21 100644 --- a/app/models/poll/booth_assignment.rb +++ b/app/models/poll/booth_assignment.rb @@ -1,5 +1,5 @@ class Poll - class BoothAssignment < ActiveRecord::Base + class BoothAssignment < ApplicationRecord belongs_to :booth belongs_to :poll diff --git a/app/models/poll/officer.rb b/app/models/poll/officer.rb index ef96cfa91..c44256a5a 100644 --- a/app/models/poll/officer.rb +++ b/app/models/poll/officer.rb @@ -1,5 +1,5 @@ class Poll - class Officer < ActiveRecord::Base + class Officer < ApplicationRecord belongs_to :user has_many :officer_assignments, class_name: "Poll::OfficerAssignment" has_many :shifts, class_name: "Poll::Shift" diff --git a/app/models/poll/officer_assignment.rb b/app/models/poll/officer_assignment.rb index 7de4f98b3..5714d8e74 100644 --- a/app/models/poll/officer_assignment.rb +++ b/app/models/poll/officer_assignment.rb @@ -1,7 +1,8 @@ class Poll - class OfficerAssignment < ActiveRecord::Base + class OfficerAssignment < ApplicationRecord belongs_to :officer belongs_to :booth_assignment + has_many :ballot_sheets has_many :partial_results has_many :recounts has_many :voters diff --git a/app/models/poll/partial_result.rb b/app/models/poll/partial_result.rb index b24ae9750..7c4a6657e 100644 --- a/app/models/poll/partial_result.rb +++ b/app/models/poll/partial_result.rb @@ -1,4 +1,4 @@ -class Poll::PartialResult < ActiveRecord::Base +class Poll::PartialResult < ApplicationRecord VALID_ORIGINS = %w{web booth} diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 03c89f0c5..22a63168a 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -1,4 +1,4 @@ -class Poll::Question < ActiveRecord::Base +class Poll::Question < ApplicationRecord include Measurable include Searchable diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index 4f901459a..b2434aa3b 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -1,4 +1,4 @@ -class Poll::Question::Answer < ActiveRecord::Base +class Poll::Question::Answer < ApplicationRecord include Galleryable include Documentable diff --git a/app/models/poll/question/answer/video.rb b/app/models/poll/question/answer/video.rb index 4804f5188..f7b9e9676 100644 --- a/app/models/poll/question/answer/video.rb +++ b/app/models/poll/question/answer/video.rb @@ -1,4 +1,4 @@ -class Poll::Question::Answer::Video < ActiveRecord::Base +class Poll::Question::Answer::Video < ApplicationRecord belongs_to :answer, class_name: "Poll::Question::Answer", foreign_key: "answer_id" VIMEO_REGEX = /vimeo.*(staffpicks\/|channels\/|videos\/|video\/|\/)([^#\&\?]*).*/ diff --git a/app/models/poll/recount.rb b/app/models/poll/recount.rb index 878b1ee55..9cd744cc0 100644 --- a/app/models/poll/recount.rb +++ b/app/models/poll/recount.rb @@ -1,4 +1,4 @@ -class Poll::Recount < ActiveRecord::Base +class Poll::Recount < ApplicationRecord VALID_ORIGINS = %w{web booth letter}.freeze diff --git a/app/models/poll/shift.rb b/app/models/poll/shift.rb index dd5c1db32..828fba66e 100644 --- a/app/models/poll/shift.rb +++ b/app/models/poll/shift.rb @@ -1,5 +1,5 @@ class Poll - class Shift < ActiveRecord::Base + class Shift < ApplicationRecord belongs_to :booth belongs_to :officer diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 1e4a0d204..522c28de2 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -1,5 +1,5 @@ class Poll - class Voter < ActiveRecord::Base + class Voter < ApplicationRecord VALID_ORIGINS = %w{web booth}.freeze diff --git a/app/models/progress_bar.rb b/app/models/progress_bar.rb index 2f494196e..c0bacc7ba 100644 --- a/app/models/progress_bar.rb +++ b/app/models/progress_bar.rb @@ -1,4 +1,4 @@ -class ProgressBar < ActiveRecord::Base +class ProgressBar < ApplicationRecord self.inheritance_column = nil RANGE = 0..100 @@ -8,6 +8,7 @@ class ProgressBar < ActiveRecord::Base translates :title, touch: true include Globalizable + translation_class_delegate :primary? validates :progressable, presence: true validates :kind, presence: true, diff --git a/app/models/progress_bar/translation.rb b/app/models/progress_bar/translation.rb deleted file mode 100644 index d61f1d47b..000000000 --- a/app/models/progress_bar/translation.rb +++ /dev/null @@ -1,3 +0,0 @@ -class ProgressBar::Translation < Globalize::ActiveRecord::Translation - delegate :primary?, to: :globalized_model -end diff --git a/app/models/proposal.rb b/app/models/proposal.rb index af5d612d9..7eb397d3f 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -1,4 +1,4 @@ -class Proposal < ActiveRecord::Base +class Proposal < ApplicationRecord include Rails.application.routes.url_helpers include Flaggable include Taggable diff --git a/app/models/proposal_notification.rb b/app/models/proposal_notification.rb index bdb9f7698..20fe1f0cb 100644 --- a/app/models/proposal_notification.rb +++ b/app/models/proposal_notification.rb @@ -1,4 +1,4 @@ -class ProposalNotification < ActiveRecord::Base +class ProposalNotification < ApplicationRecord include Graphqlable include Notifiable diff --git a/app/models/related_content.rb b/app/models/related_content.rb index f9facb47a..4a74ba3c7 100644 --- a/app/models/related_content.rb +++ b/app/models/related_content.rb @@ -1,4 +1,4 @@ -class RelatedContent < ActiveRecord::Base +class RelatedContent < ApplicationRecord RELATED_CONTENT_SCORE_THRESHOLD = Setting["related_content_score_threshold"].to_f RELATIONABLE_MODELS = %w{proposals debates budgets investments}.freeze diff --git a/app/models/related_content_score.rb b/app/models/related_content_score.rb index da37fc07d..3d7684545 100644 --- a/app/models/related_content_score.rb +++ b/app/models/related_content_score.rb @@ -1,4 +1,4 @@ -class RelatedContentScore < ActiveRecord::Base +class RelatedContentScore < ApplicationRecord SCORES = { POSITIVE: 1, NEGATIVE: -1 diff --git a/app/models/setting.rb b/app/models/setting.rb index 58d41e934..2275a3d4c 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -1,4 +1,4 @@ -class Setting < ActiveRecord::Base +class Setting < ApplicationRecord validates :key, presence: true, uniqueness: true default_scope { order(id: :asc) } diff --git a/app/models/signature.rb b/app/models/signature.rb index 3f5729058..9daf8cbe5 100644 --- a/app/models/signature.rb +++ b/app/models/signature.rb @@ -1,4 +1,4 @@ -class Signature < ActiveRecord::Base +class Signature < ApplicationRecord belongs_to :signature_sheet belongs_to :user diff --git a/app/models/signature_sheet.rb b/app/models/signature_sheet.rb index a8a10a150..86aaf8f3d 100644 --- a/app/models/signature_sheet.rb +++ b/app/models/signature_sheet.rb @@ -1,4 +1,4 @@ -class SignatureSheet < ActiveRecord::Base +class SignatureSheet < ApplicationRecord belongs_to :signable, polymorphic: true belongs_to :author, class_name: "User", foreign_key: "author_id" diff --git a/app/models/site_customization/content_block.rb b/app/models/site_customization/content_block.rb index 6903303e7..2219ef5d4 100644 --- a/app/models/site_customization/content_block.rb +++ b/app/models/site_customization/content_block.rb @@ -1,4 +1,4 @@ -class SiteCustomization::ContentBlock < ActiveRecord::Base +class SiteCustomization::ContentBlock < ApplicationRecord VALID_BLOCKS = %w[top_links footer subnavigation_left subnavigation_right] validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) } diff --git a/app/models/site_customization/image.rb b/app/models/site_customization/image.rb index e933c40a0..12a61dad8 100644 --- a/app/models/site_customization/image.rb +++ b/app/models/site_customization/image.rb @@ -1,4 +1,4 @@ -class SiteCustomization::Image < ActiveRecord::Base +class SiteCustomization::Image < ApplicationRecord VALID_IMAGES = { "logo_header" => [260, 80], "social_media_icon" => [470, 246], diff --git a/app/models/site_customization/page.rb b/app/models/site_customization/page.rb index 6dd8f8d2f..11ced8f07 100644 --- a/app/models/site_customization/page.rb +++ b/app/models/site_customization/page.rb @@ -1,4 +1,4 @@ -class SiteCustomization::Page < ActiveRecord::Base +class SiteCustomization::Page < ApplicationRecord VALID_STATUSES = %w[draft published] has_many :cards, class_name: "Widget::Card", foreign_key: "site_customization_page_id" diff --git a/app/models/spending_proposal.rb b/app/models/spending_proposal.rb index 2b6b9fd67..03fb45e79 100644 --- a/app/models/spending_proposal.rb +++ b/app/models/spending_proposal.rb @@ -1,4 +1,4 @@ -class SpendingProposal < ActiveRecord::Base +class SpendingProposal < ApplicationRecord include Measurable include Sanitizable include Taggable @@ -43,10 +43,6 @@ class SpendingProposal < ActiveRecord::Base super.try :html_safe end - def self.filter_params(params) - params.select{|x, _| %w{geozone_id administrator_id tag_name valuator_id}.include? x.to_s } - end - def self.scoped_filter(params, current_filter) results = self results = results.by_geozone(params[:geozone_id]) if params[:geozone_id].present? diff --git a/app/models/topic.rb b/app/models/topic.rb index e9e463aa5..8130c03da 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -1,4 +1,4 @@ -class Topic < ActiveRecord::Base +class Topic < ApplicationRecord acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases include Notifiable diff --git a/app/models/user.rb b/app/models/user.rb index e62b55273..35bff958a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,9 +1,9 @@ -class User < ActiveRecord::Base +class User < ApplicationRecord include Verification devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, - :trackable, :validatable, :omniauthable, :async, :password_expirable, :secure_validatable, + :trackable, :validatable, :omniauthable, :password_expirable, :secure_validatable, authentication_keys: [:login] acts_as_voter @@ -64,7 +64,7 @@ class User < ActiveRecord::Base scope :active, -> { where(erased_at: nil) } scope :erased, -> { where.not(erased_at: nil) } scope :public_for_api, -> { all } - scope :by_comments, ->(query, topics_ids) { joins(:comments).where(query, topics_ids).uniq } + scope :by_comments, ->(query, topics_ids) { joins(:comments).where(query, topics_ids).distinct } scope :by_authors, ->(author_ids) { where("users.id IN (?)", author_ids) } scope :by_username_email_or_document_number, ->(search_string) do string = "%#{search_string}%" @@ -128,7 +128,9 @@ class User < ActiveRecord::Base end def headings_voted_within_group(group) - Budget::Heading.order("name").where(id: voted_investments.by_group(group).pluck(:heading_id)) + Budget::Heading.joins(:translations) + .order("name") + .where(id: voted_investments.by_group(group).pluck(:heading_id)) end def voted_investments @@ -346,6 +348,10 @@ class User < ActiveRecord::Base followables.compact.map { |followable| followable.tags.map(&:name) }.flatten.compact.uniq end + def send_devise_notification(notification, *args) + devise_mailer.send(notification, self, *args).deliver_later + end + private def clean_document_number diff --git a/app/models/valuation_assignment.rb b/app/models/valuation_assignment.rb index a0505a8aa..2aaea14fb 100644 --- a/app/models/valuation_assignment.rb +++ b/app/models/valuation_assignment.rb @@ -1,4 +1,4 @@ -class ValuationAssignment < ActiveRecord::Base +class ValuationAssignment < ApplicationRecord belongs_to :valuator, counter_cache: :spending_proposals_count belongs_to :spending_proposal, counter_cache: true end diff --git a/app/models/valuator.rb b/app/models/valuator.rb index 2aedfc8f6..70c0a8201 100644 --- a/app/models/valuator.rb +++ b/app/models/valuator.rb @@ -1,4 +1,4 @@ -class Valuator < ActiveRecord::Base +class Valuator < ApplicationRecord belongs_to :user, touch: true belongs_to :valuator_group diff --git a/app/models/valuator_group.rb b/app/models/valuator_group.rb index 26738b542..9e8d388b5 100644 --- a/app/models/valuator_group.rb +++ b/app/models/valuator_group.rb @@ -1,4 +1,4 @@ -class ValuatorGroup < ActiveRecord::Base +class ValuatorGroup < ApplicationRecord has_many :valuators has_many :valuator_group_assignments, dependent: :destroy, class_name: "Budget::ValuatorGroupAssignment" has_many :investments, through: :valuator_group_assignments, class_name: "Budget::Investment" diff --git a/app/models/verified_user.rb b/app/models/verified_user.rb index 6b0ddb822..205c2dfe9 100644 --- a/app/models/verified_user.rb +++ b/app/models/verified_user.rb @@ -1,4 +1,4 @@ -class VerifiedUser < ActiveRecord::Base +class VerifiedUser < ApplicationRecord scope :by_user, ->(user) { where(document_number: user.document_number) } scope :by_email, ->(email) { where(email: email) } diff --git a/app/models/visit.rb b/app/models/visit.rb index 6bb47fed0..9bcf891d7 100644 --- a/app/models/visit.rb +++ b/app/models/visit.rb @@ -1,4 +1,4 @@ -class Visit < ActiveRecord::Base +class Visit < ApplicationRecord has_many :ahoy_events, class_name: "Ahoy::Event" belongs_to :user end diff --git a/app/models/web_section.rb b/app/models/web_section.rb index ffeca96f2..3c2dd5790 100644 --- a/app/models/web_section.rb +++ b/app/models/web_section.rb @@ -1,4 +1,4 @@ -class WebSection < ActiveRecord::Base +class WebSection < ApplicationRecord has_many :sections has_many :banners, through: :sections end diff --git a/app/models/widget/card.rb b/app/models/widget/card.rb index 5ec0d4944..bbc87e33b 100644 --- a/app/models/widget/card.rb +++ b/app/models/widget/card.rb @@ -1,4 +1,4 @@ -class Widget::Card < ActiveRecord::Base +class Widget::Card < ApplicationRecord include Imageable belongs_to :page, class_name: "SiteCustomization::Page", foreign_key: "site_customization_page_id" diff --git a/app/models/widget/feed.rb b/app/models/widget/feed.rb index 997f9e8b6..2ddd00d62 100644 --- a/app/models/widget/feed.rb +++ b/app/models/widget/feed.rb @@ -1,4 +1,4 @@ -class Widget::Feed < ActiveRecord::Base +class Widget::Feed < ApplicationRecord self.table_name = "widget_feeds" KINDS = %w(proposals debates processes) diff --git a/app/views/admin/budget_investments/_select_investment.html.erb b/app/views/admin/budget_investments/_select_investment.html.erb index e4c7f5355..040d128e1 100644 --- a/app/views/admin/budget_investments/_select_investment.html.erb +++ b/app/views/admin/budget_investments/_select_investment.html.erb @@ -5,7 +5,7 @@ <%= link_to investment.title, admin_budget_budget_investment_path(budget_id: @budget.id, id: investment.id, - params: Budget::Investment.filter_params(params)), + params: Budget::Investment.filter_params(params).to_h), target: "_blank" %> diff --git a/app/views/admin/budget_investments/edit.html.erb b/app/views/admin/budget_investments/edit.html.erb index 6cfcfbe63..a9c81dd39 100644 --- a/app/views/admin/budget_investments/edit.html.erb +++ b/app/views/admin/budget_investments/edit.html.erb @@ -1,11 +1,11 @@ -<%= link_to admin_budget_budget_investment_path(@budget, @investment, Budget::Investment.filter_params(params)), class: "back" do %> +<%= link_to admin_budget_budget_investment_path(@budget, @investment, Budget::Investment.filter_params(params).to_h), class: "back" do %> <%= t("shared.back") %> <% end %> <%= form_for @investment, url: admin_budget_budget_investment_path(@budget, @investment) do |f| %> - <% Budget::Investment.filter_params(params).each do |filter_name, filter_value| %> + <% Budget::Investment.filter_params(params).to_h.each do |filter_name, filter_value| %> <%= hidden_field_tag filter_name, filter_value %> <% end %> diff --git a/app/views/admin/budget_investments/show.html.erb b/app/views/admin/budget_investments/show.html.erb index 191b498ef..d364118ca 100644 --- a/app/views/admin/budget_investments/show.html.erb +++ b/app/views/admin/budget_investments/show.html.erb @@ -1,4 +1,4 @@ -<%= link_to admin_budget_budget_investments_path(Budget::Investment.filter_params(params)), +<%= link_to admin_budget_budget_investments_path(Budget::Investment.filter_params(params).to_h), class: "back", data: {no_turbolink: true} do %> <%= t("shared.back") %> <% end %> @@ -7,7 +7,7 @@ <%= link_to t("admin.budget_investments.show.edit"), edit_admin_budget_budget_investment_path(@budget, @investment, - Budget::Investment.filter_params(params)) unless @budget.finished? %> + Budget::Investment.filter_params(params).to_h) unless @budget.finished? %>
@@ -44,7 +44,7 @@

<%= link_to t("admin.budget_investments.show.edit_classification"), edit_admin_budget_budget_investment_path(@budget, @investment, - {anchor: "classification"}.merge(Budget::Investment.filter_params(params))) unless @budget.finished? %> + {anchor: "classification"}.merge(Budget::Investment.filter_params(params).to_h)) unless @budget.finished? %>


diff --git a/app/views/admin/budgets/index.html.erb b/app/views/admin/budgets/index.html.erb index 2be3ae926..c63ee4789 100644 --- a/app/views/admin/budgets/index.html.erb +++ b/app/views/admin/budgets/index.html.erb @@ -17,6 +17,7 @@ <%= t("admin.budgets.index.table_investments") %> <%= t("admin.budgets.index.table_edit_groups") %> <%= t("admin.budgets.index.table_edit_budget") %> + <%= t("admin.budgets.index.table_admin_ballots") %> @@ -39,6 +40,13 @@ <%= link_to t("admin.budgets.index.edit_budget"), edit_admin_budget_path(budget) %> + + <% if budget.poll.present? %> + <%= link_to t("admin.budgets.index.admin_ballots"), admin_poll_booth_assignments_path(budget.poll) %> + <% else %> + <%= link_to_create_budget_poll(budget) %> + <% end %> + <% end %> diff --git a/app/views/admin/poll/booth_assignments/index.html.erb b/app/views/admin/poll/booth_assignments/index.html.erb index 9e99e3179..d28d98989 100644 --- a/app/views/admin/poll/booth_assignments/index.html.erb +++ b/app/views/admin/poll/booth_assignments/index.html.erb @@ -11,7 +11,7 @@ class: "button hollow float-right" %> <% if @booth_assignments.empty? %> -
+
<%= t("admin.poll_booth_assignments.index.no_booths") %>
<% else %> diff --git a/app/views/admin/poll/polls/_subnav.html.erb b/app/views/admin/poll/polls/_subnav.html.erb index 98e23003b..f72176a9e 100644 --- a/app/views/admin/poll/polls/_subnav.html.erb +++ b/app/views/admin/poll/polls/_subnav.html.erb @@ -1,18 +1,20 @@