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.
The application crashed when we generated hints to attributes with
interpolation arguments in their `human_attribute_name`.
When generating the hint, we used the `custom_label` method to generate
a label and get the `for` attribute and, since we weren't passing a
text, it used the default human attribute name for the field. However,
it crashes if the default attribute name requires an interpolation
argument.
So now, since we were only using the `custom_label` method in order to
get the `for` attribute, we're simply passing an arbitrary text to the
method.
One of these tests was failing sometimes on Github Actions. It looked
like the line `custom_banner.save!` was using the validations from the
Banner class sometimes, even if the callbacks had correctly been
removed in the DummyBanner class.
Se we're inheriting from ApplicationRecord instead of inheriting from
Banner. Since I couldn't reproduce the issue locally after running the
test hundreds of times and with the same seed and tests that were
running on Github Actions, there's a change this won't work. I've tested
a few times on Github Actions and it seems to be working, but we'll have
to keep an eye on it.
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>
We were getting a warning in Rails 6.0:
DEPRECATION WARNING: Class level methods will no longer inherit scoping
from `public_for_api` in Rails 6.1. To continue using the scoped
relation, pass it into the block directly. To instead access the full
set of models, as Rails 6.1 will, use
`ActsAsTaggableOn::Tag.default_scoped`.
In SQL, conditions like:
```
tag_id IN (x) AND taggable_type='Debate' OR taggable_type='Proposal'
```
Don't work as intended; we need to write:
```
tag_id IN (x) AND (taggable_type='Debate' OR taggable_type='Proposal')
```
Due to this bug, we were returning taggings for proposals without
intending to do so.
Since the code was very hard to read, we're also simplifying it.
We were getting a warning in Rails 6:
DEPRECATION WARNING: ActionView::Base instances should be constructed
with a lookup context, assignments, and a controller.
We did a similar change in commit 47925fbab, and we were getting a
warning in Rails 6.0:
DEPRECATION WARNING: render file: should be given the absolute path to a
file
Since using `render file:` would ignore views in custom folders, we're
using `render template:` instead.
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.
When there was a custom JavaScript file, we weren't loading the original
one, meaning that, in order to customize it, it was necessary to copy
the whole original file and then changing it.
Now we're loading both the original and the custom file, so the custom
file can simply add more functions or overwrite the ones we'd like to
customize, without copying the whole file.
Existing copies of original files will still overwrite the whole file
and won't be affected.
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.
This way we don't have to write `"spec/fixtures/files"` every time.
Note this method isn't included in factories. We could include it like
so:
```
FactoryBot::SyntaxRunner.class_eval do
include ActiveSupport::Testing::FileFixtures
self.file_fixture_path = RSpec.configuration.file_fixture_path
end
```
However, I'm not sure about the possible side effects, and since we only
use attachments in a few factories, there isn't much gain in applying
the monkey-patch.
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.
This fixes a few issues we've had for years.
First, when attaching an image and then sending a form with validation
errors, the image preview would not be rendered when the form was
displayed once again. Now it's rendered as expected.
Second, when attaching an image, removing it, and attaching a new
one, browsers were displaying the image preview of the first one. That's
because Paperclip generated the same URL from both files (as they both
had the same hash data and prefix). Browsers usually cache images and
render the cached image when getting the same URL.
Since now we're storing each image in a different Blob, the images have
different URLs and so the preview of the second one is correctly
displayed.
Finally, when users downloaded a document, they were getting files with
a very long hexadecimal hash as filename. Now they get the original
filename.
This way we fix a bug we mentioned in commit 930bb753c which caused
links to documents to be broken when editing their title because the
title was used to generate the URL of the document.
Note we're still using Paperclip to render cached attachments because
this is the only case where we store files with just Paperclip and not
Active Storage.
With Active Storage, we render attachments just like any other resource,
using `polymorphic_path`. Paperclip included the `url` method in the
model; since the model doesn't have access to the request parameters
(like the host), this was inconvenient because it wasn't possible to
generate absolute URLs with Paperclip.
In order to simplify the code and make it similar to the way we used
Paperclip, we're adding a `variant` method accepting the name of a
variant and returning the variant.