So now we'll be able to add them to other sections.
We're also adding a `dependent: :destroy` relation to models having
cards since it doesn't make sense to have cards around when their page
has been destroyed.
We didn't add any validation rules to the card model. At the very least,
the title should be mandatory.
The fact that the label field is marked as optional in the form but the
other fields are not probably means description and link should be
mandatory as well. However, since there might be institutions using
cards with descriptions but no link or cards with links but no
description, so we're keeping these fields optional for compatibility
reasons. We might change our minds in the future, though.
Not doing so has a few gotchas when working with relations, particularly
with records which are not stored in the database.
I'm excluding the related content file because it's got a very peculiar
relationship with itself: the `has_one :opposite_related_content` has no
inverse; the relation itself is its inverse. It's a false positive since
the inverse condition is true:
```
content.opposite_related_content.opposite_related_content.object_id ==
content.object_id
```
We were very inconsistent regarding these rules.
Personally I prefer no empty lines around blocks, clases, etc... as
recommended by the Ruby style guide [1], and they're the default values
in rubocop, so those are the settings I'm applying.
The exception is the `private` access modifier, since we were leaving
empty lines around it most of the time. That's the default rubocop rule
as well. Personally I don't have a strong preference about this one.
[1] https://rubystyle.guide/#empty-lines-around-bodies
Having exceptions is better than having silent bugs.
There are a few methods I've kept the same way they were.
The `RelatedContentScore#score_with_opposite` method is a bit peculiar:
it creates scores for both itself and the opposite related content,
which means the opposite related content will try to create the same
scores as well.
We've already got a test to check `Budget::Ballot#add_investment` when
creating a line fails ("Edge case voting a non-elegible investment").
Finally, the method `User#send_oauth_confirmation_instructions` doesn't
update the record when the email address isn't already present, leading
to the test "Try to register with the email of an already existing user,
when an unconfirmed email was provided by oauth" fo fail if we raise an
exception for an invalid user. That's because updating a user's email
doesn't update the database automatically, but instead a confirmation
email is sent.
There are also a few false positives for classes which don't have bang
methods (like the GraphQL classes) or destroying attachments.
For these reasons, I'm adding the rule with a "Refactor" severity,
meaning it's a rule we can break if necessary.
This code was introduced in commit 722a431b, but it stopped being used
in commit 7657a0e0.
The spec was failing sometimes because the method didn't order the
records, but the spec checked the records returned in a certain order.
Furthermore, the method `page` generated a potential conflict with
kaminari's `page method.
We need to add an ORDER BY clause; not doing so was causing different
processes to show up sometimes. As mentioned in the PostgreSQL manual:
> Because the order of the rows in the database table is unpredictable,
> when you use the LIMIT clause, you should always use the ORDER BY
> clause to control the order of rows. If you don’t do so, you will get
> an unpredictable result set.
The condition `params[:page_id] != 0` didn't work properly when editing
the homepage because in that case the parameter was `nil`, and the line
`SiteCustomization::Page.find(@card.site_customization_page_id)` raised
an exception because it couldn't find a page with a `nil` ID.
Fixing the issue while maintaining the check against `0` lead to complex
code, and so allowing `nil` in the database and assuming cards with no
`site_customization_page_id` belonged in the homepage seemed to be the
easiest solution.
Note there is some funkiness going on with class loadings
Had to create a `feed` and `widget_feed` table even though in this
first version the Widget::Feed includes only uses ActiveModel instead
of ActiveRecord, otherwise some specs failed
We’ll figure it out and clean up 😌