We were already saving it as a time, but we didn't offer an interface to
select the time due to lack of decent browser support for this field
back when this feature was added.
However, nowadays all major browsers support this field type and, at the
time of writing, at least 86.5% of the browsers support it [1]. This
percentage could be much higher, since support in 11.25% of the browsers
is unknown.
Note we still need to support the case where this field isn't supported,
and so we offer a fallback and on the server side we don't assume we're
always getting a time. We're doing a strange hack so we set the field
type to text before changing its value; otherwise old Firefox browsers
crashed.
Also note that, until now, we were storing end dates in the database as
a date with 00:00 as its time, but we were considering the poll to be
open until 23:59 that day. So, in order to keep backwards compatibility,
we're adding a task to update the dates of existing polls so we get the
same behavior we had until now.
This also means budget polls are now created so they end at the
beginning of the day when the balloting phase ends. This is consistent
with the dates we display in the budget phases table.
Finally, there's one test where we're using `beginning_of_minute` when
creating a poll. That's because Chrome provides an interface to enter a
time in a `%H:%M` format when the "seconds" value of the provided time
is zero. However, when the "seconds" value isn't zero, Chrome provides
an interface to enter a time in a `%H:%M:%S` format. Since Capybara
doesn't enter the seconds when using `fill_in` with a time, the test
failed when Capybara tried to enter a time in the `%H:%M` format when
Chrome expected a time in the `%H:%M:%S` format.
To solve this last point, an alternative would be to manually provide
the format when using `fill_in` so it includes the seconds.
[1] https://caniuse.com/mdn-html_elements_input_type_datetime-local
This was the only place where we used the `? <= field` format; we use
the `field >= ?` format everywhere else.
We're also adding a variable to make it easier to understand that the
value is the same in both cases and to make the line shorter ;).
Actions :search_booths and :search_officers in admin polls controller
are moved to other controllers since commit 20e31133a for
:search_booths and commit 19ec7f93b for :search_officers.
This then allows us to remove the code that references these actions in
the controller and in the administrator abilities.
It's now used by default to handle image variants. We were getting a
warning:
DEPRECATION WARNING: Generating image variants will require the
image_processing gem in Rails 6.1. Please add `gem 'image_processing',
'~> 1.2'` to your Gemfile.
Note `mini_magick` is required in order to use the `analyze` method [1].
Since we use it in our image (and site customization image) validations,
we're still keeping the explicit dependency in our Gemfile.
[1] https://guides.rubyonrails.org/v6.0/active_storage_overview.html#analyzing-files
All the code in the `bin/` and the `config/` folders has been generated
running `rake app:update`. The only exception is the code in
`config/application.rb` where we've excluded the engines that Rails 6.0
has added, since we don't use them.
There are a few changes in Active Storage which aren't compatible with
the code we were using until now.
Since the method to assign an attachment in ActiveStorage has changed
and is incompatible with the hack we used to allow assigning `nil`
attachments, and since ActiveStorage now supports assigning `nil`
attachments, we're removing the mentioned hack. This makes the
HasAttachment module redundant, so we're removing it.
Another change in ActiveStorage is files are no longer saved before
saving the `ActiveStorage::Attachment` record. This means we need to
manually upload the file when using direct uploads. We also have to
change the width and height validations we used for images; however,
doing so results in very complex code, and we currently have to write
that code for both images and site customization images.
So, for now, we're just uploading the file before checking its
dimensions. Not ideal, though. We might use active_storage_validations
in the future to fix this issue (when they support a proc/lambda, as
mentioned in commit 600f5c35e).
We also need to update a couple of tests due to a small change in
response headers. Now the content disposition returns something like:
```
attachment; filename="budget_investments.csv"; filename*=UTF-8''budget_investments.csv
```
So we're updating regular expression we use to check the filename.
Finally, Rails 6.0.1 changed the way the host is set in integration
tests [1] and so both `Capybara.app_host` and `Capybara.default_host`
were ignored when generating URLs in the relationable examples. The only
way I've found to make it work is to explicitely assign the host to the
integration session. Rails 6.1 will change this setup again, so maybe
then we can remove this hack.
[1] https://github.com/rails/rails/pull/36283/commits/fe00711e9
We introduced this bug in commit 55d339572, since we didn't take hidden
records into consideration.
I've tried to use `update_column` to simplify the code, but got a syntax
error `unnamed portal parameter` and didn't find how to fix it.
When we added this setting in commit 9979b5399, we disabled it by
default so it would be compatible with existing installations.
Since then, we've released version 1.4, which adds the settings to
existing databases. That means we can now enable it by default and
existing installations won't be affected.
The current consul GraphQL API has two problems.
1) It uses some unnecessary complicated magic to automatically create
the GraphQL types and querys using an `api.yml` file. This approach
is over-engineered, complex and has no benefits. It's just harder to
understand the code for people which are not familiar with the
project (like me, lol).
2) It uses a deprecated DSL [1] that is soon going to be removed from
`graphql-ruby` completely. We are already seeing deprecation warning
because of this (see References).
There was one problem. I wanted to create the API so that it is fully
backwards compatible with the old one, BUT the old one uses field names
which are directly derived from the ruby code, which results in
snake_case field names - not the GraphQL way. When I'm using the
graphql-ruby Class-based syntax, it automatically creates the fields in
camelCase, which breaks backwards-compatibility.
So I've added deprecated snake_case field names to keep it
backwards-compatible.
[1] https://graphql-ruby.org/schema/class_based_api.html
On the Configuration settings page three settings appeared without
description:
* Comments Summary: No description.
* Related Content: No description.
* Tags: No description.
These settings are related with the AI / Machine learning feature. They
only should appear on AI / Machine learning setting page when the
feature is enabled.
After a user assigned as a budget admin deletes their account or gets blocked by
a moderator, the application throws an exception while loading the admin
investment index page.
As an erased user is not really deleted and neither its associated roles, the
application was failing when trying to sort and administration without a
username. In this case, the application was throwing an `ArgumentError:
comparison of NilClass with String failed` exception.
As a blocked user is not deleted or its roles, the application failed when trying
to access the user name through the delegation in the Administrator. In this
case, the application was throwing a `NoMethodError: undefined method `name' for
nil:NilClass` exception.
Add missing relation between administrator and budget_administrators, otherwise
we'd get the following exception when deleting and administrator with assigned budgets:
PG::ForeignKeyViolation:
ERROR: update or delete on table "administrators" violates foreign key constraint "fk_rails_ee7dc33688" on table "budget_administrators"
DETAIL: Key (id)=(3) is still referenced from table "budget_administrators".
We were returning an (empty) association of users instead of empty
associations of proposals, debates or comments. The code worked because
in the end it returned an empty array, but looked weird nevertheless.
After commit 0214184b2, this method was only used in two places and was
only useful in one of them. IMHO it isn't worth it add a monkey-patch
for such a minor usage.
Avoid displaying the price in admin budget headings section
and avoid fill the field 'price' in admin budget headings form
when the budget has been checked with hide_money field.
There are CONSUL installations where the validations CONSUL offers by
default don't make sense because they're using a different business
logic. Removing these validations in a custom model was hard, and that's
why in many cases modifying the original CONSUL models was an easier
solution.
Since modifying the original CONSUL models makes the code harder to
maintain, we're now providing a way to easily skip validations in a
custom model. For example, in order to skip the price presence
validation in the Budget::Heading model, we could write a model in
`app/models/custom/budget/heading.rb`:
```
require_dependency Rails.root.join("app", "models", "budget", "heading").to_s
class Budget::Heading
skip_validation :price, :presence
end
```
In order to skip validation on translatable attributes (defined with
`validates_translation`), we have to use the
`skip_translation_validation` method; for example, to skip the proposal
title presence validation:
```
require_dependency Rails.root.join("app", "models", "proposal").to_s
class Proposal
skip_translation_validation :title, :presence
end
```
Co-Authored-By: taitus <sebastia.roig@gmail.com>
The `only:` key does not apply to model callbacks. It was added in commit 1077e25b2, probably by accident.
Using this key raises an error in Rails 6.0.
We were using this hack in order to allow `File.new` attachments in
tests files. However, we can use the `fixture_file_upload` helper
instead.
Just like it happened with `file_fixture`, this helper method doesn't
work in fixtures, so in this case we're using `Rack::Test::UploadedFile`
instead.
We were using custom rules because of some issues with Paperclip. These
rules work fine, but since we're already using the file_validators gem,
we might as well simplify the code a little bit.
The code is based on what's generated using CKEditor's code generator.
We're doing one minor change to the `Ckeditor::Backend::ActiveStorage`
module; we're assigning the data in a `before_validation` instead of a
`before_save` callback. Validations with `file_validations` didn't work
otherwise; it looks like this backend was written with
`active_storage_validations` in mind [1].
Note we don't need to update the `name` column in the attachments table
because, when using Active Storage, CKEditor uses both `data` (as
attribute accessor) and `storage_data` (as attachment attribute).
[1] https://github.com/galetahub/ckeditor/blob/f9e48420ccb6dc/lib/generators/ckeditor/templates/active_record/active_storage/ckeditor/picture.rb#L4
Since we're going to remove Paperclip and Active Storage doesn't provide
any validations, we have to either write our own validation rules or use
a different gem.
We're using the file_validators gem instead of the
`active_storage_validations` gem because the latter doesn't support
proc/lambda objects in size and content type definitions. We need to use
them because in our case these values depend on settings stored in the
database.
Just like we did with regular attachments, we're moving the logic to
generate URLs out of the model.
Note we're changing the `image_path_for` helper method in order to
return a `polymorphic_path` because sometimes it's used in combination
with `favicon_link_tag`, and `favicon_link_tag` doesn't automatically
generate a polymorphic URL when given an `ActiveStorage::Attachment`
record.