Add link_url presence validation only when link_text is provided only for header cards.
In this case it makes sense to allow creating a "header card" without link_url, since
we can show the header without link text and without link url and it still does its
function.
Currently it is not necessary to include the link_url field.
When we display these cards without link_url, they create an empty link that
redirects to the same page. I understand that this is not a desired behavior, so I
think it is better to add a validation in this case and force administrators to add a
link_url when creating a card.
It looks like this bug was introduced in commit 7ca55c4. Before that
commit, a message saying "You added a new related content" was shown,
but (as expected) the related content wasn't added twice.
We now check this case and add a slightly clearer message.
Although it wasn't a real security concern because we were only calling
a `find_by` method based on the user input, it's a good practice to
avoid using constants based on user parameters.
Since we don't use the `find_by` method anymore but we still need to
check the associated record exists, we're changing the validations in
the `RelatedContent` model to do exactly that.
We were manually checking validation rules (like both relationable
objects are present, or they're both the same object) in the controller
and then using the `save!` method.
However, we usually use the `save` method (which checks all validations)
in a condition, and proceed depending on the result.
Now we're taking the same approach here. This means introducing a new
validation rule in the model to check whether both relationable objects
are the same, which is more robust than checking a condition in the
controller.
Note we don't cast negative votes when users remove their support. That
way we provide compatibility for institutions who have implemented real
negative votes (in case there are / will be any), and we also keep the
database meaningful: it's not that users downvoted something; they
simply removed their upvote.
Co-Authored-By: Javi Martín <javim@elretirao.net>
Co-Authored-By: Julian Nicolas Herrero <microweb10@gmail.com>
Since we're going to add an action to remove supports, having a separate
controller makes things easier.
Note there was a strange piece of code which assumed users were not
verified if they couldn't vote investments. Now the code is also
strange, since it assumes users are not verified if they can't create
votes. We might need to revisit these conditions if our logic changes in
the future.
In the previous commit I mentioned:
> If I'm right, the `investment_votes` instance variable only exists to
> avoid several database queries to get whether the current user has
> supported each of the investments.
>
> However, that doesn't make much sense when only one investment is
> shown.
Now let's discuss the case when there are several investments, like in
the investments index:
* There are 10 investments per page by default
* Each query takes less than a millisecond
* We still make a query per investment to check whether the current user
voted in a different group
* AFAIK, there have been no performance tests showing these
optimizations make the request to the investments index significantly
faster
* These optimizations make the code way more complex than it is without
them
Considering all these points, I'm removing the optimizations. I'm fine
with adding `includes` calls to preload records and avoid N+1 queries
even if there are no performance tests showing they make the application
faster because the effect on the code complexity is negligible. But
that's not the case here.
Note we're using `defined?` instead of the `||=` operator because the
`||=` operator will not serve its purpose when the result of the
operation returns `false`.
In the form of creating a new investment was hiding the name of the
group if it had only one heading, but could be confusing to users if
there are, for example, five different groups of one heading.
The solution:
- If the budget has one group and one heading, the heading selector is
hidden.
- If the budget has one group and more than one heading, the group name
is hidden.
- If the budget has more than one group, the group name appears
regardless of the number of headings.
- Allow to define a link (text and url) on budget form for render on the budget
header.
- Improve styles
Co-authored-by: Senén Rodero Rodríguez <senenrodero@gmail.com>
So now there's no need to edit each phase individually to enable/disable
them.
We aren't doing the same thing in the form to edit a budget because we
aren't sure about possible usability issues. On one hand, in some tables
we automatically update records when we mark a checkbox, so users might
expect that. On the other hand, having a checkbox in the middle of a
form which updates the database automatically is counter-intuitive,
particularly when right below that table there are other checkboxes
which don't update the database until the form is submitted.
So, either way, chances are users would think they've updated the phases
(or kept them intact) while the opposite would be true.
In the form within the wizard to create a budget that problem isn't that
important because there aren't any other fields in the form and it's
pretty intuitive that what users do will have no effect until they press
the "Finish" button.
Co-Authored-By: Julian Nicolas Herrero <microweb10@gmail.com>
In this case, the duration of the budget cannot be determined, and the
application was crashing when trying to do so.
Now we're just returning `nil` as duration.
We don't allow deleting a budget with associated investments. However,
we allow deleting a budget with associated administrators and valuators.
This results in a foreign key violation error:
PG::ForeignKeyViolation: ERROR: update or delete on table "budgets"
violates foreign key constraint "fk_rails_c847a52b1d" on table
"budget_administrators"
Using the `dependent: :destroy` option when defining the relationship,
we remove the association records when removing the budget.
As a bonus, we reduce the number of Rubocop offenses regarding the
`Rails/HasManyOrHasOneDependent` rule. Only 72 to go! :)
When configuring phases in a process, we were validating the start date
or the end date is present, the other date is present too.
However, in other parts of the application we were checking whether a
phase is enabled and then assumed its dates were present if the phase
was enabled. However, we weren't validating this behavior, so it was
possible to enable a phase and leaving its dates blank, causing the
application to crash.
So, as suggested by Alberto, we're changing the validation rule so
phase dates are mandatory when a phase is enabled.
With this rule, the old validation rules are not necessary. I've
considered leaving them in order to avoid database inconsistencies.
However, I realized records having a disabled phase with its start and
end dates have always been valid. This means applications checking for
the presence of these dates instead of checking whether the phase is
enabled have never worked properly.
We don't have to change the logic anywhere else because as mentioned we
were already checking phases are enabled before using their dates.
In order to ensure compatibility with existing CONSUL installations, we
disabled all settings related to SDG. However, we also made it much
harder to enable SDG globally on the site, since administrators first
had to enable the SDG feature and then enable it for each process.
Most people will expect SDG is enabled for all processes once they
enable the SDG feature, so that's what we're doing. They can of course
disable specific processes should they wish to do so.
Although it wasn't a real security concern because we were only calling
a `find` method based on the user input, it's a good practice to avoid
using constants based on user parameters.
Since we don't use the `find` method anymore but we still need to check
the associated record exists, we're changing the `followable` validation
in the `Follow` model to do exactly that.
Since the :post_started_at and :post_ended_at fields are of type Date, we check
with Date.current and not with Time.current.
This change has been caused because some test suites were failing
(https://github.com/consul/consul/runs/2170798218?check_suite_focus=true).
The code we had was causing the banners to be available a few hours earlier
or later than they should be depending on the time zone of the application.
In this page we will render a list of clickable Goals icons that will show their
targets and related local targets
Co-authored-by: Senen <senenrodero@gmail.com>
Note we're making the validation rule dynamic so it's affected by the
way we stub the constant in the tests to emulate data created in old
applications.
Co-Authored-By: Javi Martín <javim@elretirao.net>