The page should not show any headings which don't have any
winning investments. The "no content" message should only be
shown when there are no headings with investments to avoid an
otherwise blank page.
__Note:__ in the main @headings query, _both_ #includes and #joins
are needed to:
1. eager load all necessary data (#includes)
and
2. to perform an INNER JOIN on milestones to filter out investments
with no milestones (#joins).
This commit makes 3 changes:
1. Extracts a query into a helper for clarity and DRYness
2. Adds a `.where` clause to filter investments based on their
(current) milestone status
3. Fixes a bug where investments would be rendered as many times as
milestones associated to an investment
This way we can show/hide that div when displaying translations, and we
can remove the duplication applying the same logic to the label, the
input, the error and the CKEditor.
This way we also solve the problem of the textarea of the CKEditor
taking space when we switch locales, as well as CKEditor itself taking
space even when not displayed.
We needed to bring back support for CKEditor in our translatable form,
which we had temporarily remove.
And now we support CKEditor in our translatable specs, and so we can
remove the duplicated specs for poll question answers.
Updating it required reorganizing the form so translatable fields are
together.
We also needed to add a `hint` option to the form label and input
methods so the hint wouldn't show up for every language.
Finally, the markdown editor needed to use the same globalize attributes
as inputs, labels and hints, which adds a bit of duplication.
After removing a translation while editing another one with invalid data
and sending the form, we were displaying the removed translation to the
user.
We now remove that translation from the form, but we don't remove it
from the database until the form has been sent without errors.
After adding a new translation with invalid data and sending the form,
we were disabling the new translation when displaying the form again to
the user, which was confusing.
Creating a new form builder might be too much. My idea was so the view
uses more or less the same syntax it would use with Rails' default
builder, and so we can use `text_field` instead of
`translatable_text_field`.
This change forces us to use nested attributes for translations, instead
of using the more convenient `:"title_#{locale}"` methods.
On the other hand, we can use Rails' native `_destroy` attribute to
remove existing translations, so we don't have to use our custom
`delete_translations`, which was a bit buggy since it didn't consider
failed updates.
There where two issues with the current implementation:
- There was a possible duplication between looking up the language name in key "locale" and in key "i18n.language.name"
- The "default" option was not being picked up, as the fallback always returned the default locale's translation, "English"
With this implementation there is only a single place to put the language name: i18n.language.name. I think this place is easier to find and understand for Crowdin translators than a "locale" key hidden in general.yml
If the translation is not found we display the language key, instead of English, which makes more sense to me too 😌
Solution based on recent comments[1] on a related I18n issue
[1] https://github.com/svenfuchs/i18n/issues/365#issuecomment-419263847
This required changing the `voted_before_sign_in` slightly in order to
change what the method returns if the user signed in and voted at the
exact same microsecond.
It doesn't affect production code because it would be impossible for the
user to do both things at the same time.
As a side effect, the method now returns what the method name suggests.
Before this change, the correct method name would have been
`voted_before_or_at_the_same_time_of_sign_in`.
As a less desirable side effect, in the tests now we need to make sure
at least one second passes between the moment a user votes and the
moment a user signs in again. One microsecond wouldn't work because
the method `travel_to` automatically sets microseconds to zero in order
to avoid rounding issues.
By doing so and including it in ActionDispatch::Routing::UrlFor, we make
it available in controllers, helpers and specs, and so we can remove the
duplication we had there with methods dealing with the same problem.
Even if monkey-patching is ugly, using a different module and executing
ActionDispatch::Routing::UrlFor.send(:include, MyModule) wouldn't make
the method available in the controller.
It turns out it is not necessary to downcase and underscore
locale names to use the globalize-accessor gem. The gem
will automatically underscore the locale name when defining and
calling the accessor methods.