Forem Creators and Builders 🌱

Christina Gorton for Forem Core Team

Posted on • Updated on

Changelog: Rails 6 upgrade, @-Mention Autocomplete, Optimizations and moreπŸŽ‰

This cycle our team tackled some big improvements for the Forem ecosystem. This post is a round up of the latest changes from our repository.

Rails 6.1

Upgrading to Rails 6 was a journey for our team that included multiple Forem team members, external contributors, and a lot of conversation.
Shout out to our open source contributors Elia Schito, Phil Coggins, and Alberto Vena who helped drive the conversation in this PR along with Forem core team members @rhymes , @joshpuetz , and @vaidehijoshi .

Upgrade Rails to 6.1.3.1 #11333

What type of PR is this? (check all applicable)

  • [ ] Refactor
  • [ ] Feature
  • [ ] Bug Fix
  • [x] Optimization
  • [ ] Documentation Update

Description

Rails is at 6.1.0.rc1, so I'm going to use this PR to track it until it's released and our gems have been updated.

update: Rails 6.1 is out: https://weblog.rubyonrails.org/2020/12/9/Rails-6-1-0-release/

Notable changes that might be of interest for us

railties

Change the default logging level from :debug to :info to avoid inadvertent exposure of personally identifiable information (PII) in production environments.

The autoloading guide for Zeitwerk mode documents how to autoload classes during application boot in a safe way.

Add config.generators.after_generate for processing to generated files.

actionpack

Change ActionDispatch::Response#content_type to return the full Content-Type header.

When multiple domains are specified for a cookie, a domain will now be chosen only if it is equal to or is a superdomain of the request host.

ActionDispatch::Static handles precompiled Brotli (.br) files.

brotli FTW

Add raise_on_missing_translations support for controllers.

fixture_file_upload now uses path relative to file_fixture_path

url_for will now use "https://" as the default protocol when Rails.application.config.force_ssl is set to true.

Support rolling deploys for cookie serialization/encryption changes.

neat as we have rolling deploys on Heroku

Add SameSite protection to every written cookie.

(disabled by default)

Bring back the feature that allows loading external route files from the router.

Yes! We can finally split the routes file in more manageable chunks :-)

ActionController::Base.log_at allows setting a different log level per request.

this might be useful during debugging

Add DSL for configuring HTTP Feature Policy.

this might be interesting to control which browser's API are enabled where

actionview

activerecord

where.not now generates NAND predicates instead of NOR.

Add values_at method. Returns an array containing the values associated with the given methods.

Allow associations supporting the dependent: key to take dependent: :destroy_async. :destroy_async will enqueue a job to destroy associated records in the background.

This should help!

Allow where references association names as joined table name aliases. Comment.includes(:children).where("children.label": "child")

finally!

Respect the select values for eager loading.

Allow default to be configured for Enum.

We can finally set a default to enum!

Add basic support for CHECK constraints to database migrations.

I'm not crying, you're crying 😭

Add ActiveRecord::Base.strict_loading_by_default and ActiveRecord::Base.strict_loading_by_default= to enable/disable strict_loading mode by default for a model. The configuration's value is inheritable by subclasses, but they can override that value and it will not impact parent class. Add support for strict_loading mode on association declarations.

This can be useful if we want to enable it on models we want to ensure they are always loaded eagerly

Add support for if_exists option for removing an index. Add support for if_not_exists option for adding index. add_index :users, :account_id, if_not_exists: true

❀️

Add ActiveRecord::Base#previously_new_record? to show if a record was new before the last save.

cool!

Support descending order for find_each, find_in_batches, and in_batches. This change allows reversing the order, batching from newest to oldest. This is useful when you need to process newer batches of records first.

πŸ”₯ this is going to be super useful in data update script, if we want newer records to be operated on first in large tables πŸ”₯

Adds support for if_not_exists to add_column and if_exists to remove_column.

Love this, migrations are getting smarter and smarter

Find orphans by looking for missing relations through chaining where.missing: Post.where.missing(:author)

This is neat!

Allow adding nonnamed expression indexes to be revertible. Previously, the following code would raise an error, when executed while rolling back, and the index name should be specified explicitly. Now, the index name is inferred automatically. add_index(:items, "to_tsvector('english', description)")

YES!

activemodel

Encapsulate each validation error as an Error object. The ActiveModel’s errors collection is now an array of these Error objects, instead of messages/details hash. For each of these Error object, its message and full_message methods are for generating error messages. Its details method would return error’s extra parameters, found in the original details hash

activesupport

require_dependency has been documented to be obsolete in :zeitwerk mode. The method is not deprecated as such (yet), but applications are encouraged to not use it. In :zeitwerk mode, semantics match Ruby's and you do not need to be defensive with load order. Just refer to classes and modules normally. If the constant name is dynamic, camelize if needed, and constantize.

Cool to know!

Add 3rd person aliases of Symbol#start_with? and Symbol#end_with?.

This has been bothering me for the longest time.

Add Date and Time #yesterday? and #tomorrow? alongside #today?.

neat

Support prepend with ActiveSupport::Concern.

Related Tickets & Documents

QA

  1. boot the app
  2. click around and test the main areas, create an articles, leave a comment, make sure everything is working

Added tests?

  • [ ] Yes
  • [x] No, and this is why: we need current tests to pass for the upgrade, new tests are not needed in this upgrade branch
  • [ ] I need help with writing tests

Analytics for all Users

This PR removes the β€œPro” role that was only available to a select group of users, and gives access to analytics to every user on Forem. You can read more about this change in the post Changelog: Analytics for All!

If you try out this new feature and find any bugs, please report them in our repository.
If you would like to give feedback on ways this feature can be improved, feel free to create a post here on forem.dev.

Remove pro role + expose analytics to all users via dashboard #13156

What type of PR is this? (check all applicable)

  • [x] Refactor
  • [x] Feature
  • [ ] Bug Fix
  • [ ] Optimization
  • [x] Documentation Update

Description

Related Tickets & Documents

Closes https://github.com/forem/internalEngineering/issues/403.

QA Instructions, Screenshots, Recordings

To QA this feature, first make sure that you have a user locally who does not have the :pro role:

pry(main)> u = User.find_by(username: 'your-username-goes-here')
=> #<User id: ...>
]pry(main)> u.has_role? :pro
=> false
Enter fullscreen mode Exit fullscreen mode

QA Instructions, Part I:

  1. Try going to /dashboard. On the bottom left of the sidebar, you should see an Analytics option in the menu. Click on that:

Screen_Shot_2021-03-28_at_4_00_05_PM

  1. Clicking on that should take you to your "Analytics Dashboard", which previously was the "Pro dashboard". Make sure there is no "pro" language (everything should read "analytics dashboard):

Screen Shot 2021-03-28 at 4 00 24 PM

3. Now, go to any article you have published (if you haven't published any, create a quick test post).

Screen_Shot_2021-03-28_at_4_00_50_PM

4. You should see a dashboard to manage your post. Notably, you should see a `Stats` button (which used to only be rendered for "pro" users). Click on that button:

Screen_Shot_2021-03-28_at_4_01_13_PM

5. You'll now be able to see the stats for your article on a `/stats` route, which should render analytics that are _specific_ to the article you were just looking at:

Screen Shot 2021-03-28 at 4 01 24 PM

QA Instructions, Part II:

  1. Create an organization (here's the route to do so).
  2. Go back to your /dashboard. Note that the Analytics option still renders as before, only now you also should see an Analytics [Your Org Name option as well (click on that one!):

Screen_Shot_2021-03-28_at_4_04_42_PM

3. Now, you should see the analytics dashboard for _your_ specific organization:

Screen Shot 2021-03-28 at 4 31 19 PM

4. Write a post under your organization and go to that post, and click `Manage` to go to the dashboard for your newly-published article, which was published under your specific organization (the route should look something like `/llamafans/this-post-is-for-llama-fans-only-43fl/manage`. You should see the organization name render in the top left corner, and you should see a `Stats` button as well. Click on the `Stats` button:

Screen_Shot_2021-03-28_at_4_04_53_PM

5. You should be taken to an article-specific analytics dashboard for the organization you are a part of!

Screen Shot 2021-03-28 at 4 05 02 PM

QA Instructions, Part III:

  1. Assign your user either an :admin or :super_admin role, and go to /admin/users. Select a user to edit, and scroll down to the "User Status" section of the page. Click the dropdown, and ensure that the Pro role does not show up there:

Screen Shot 2021-03-28 at 3 58 48 PM

2. Feel free to check for anywhere else on the site or in the codebase where the notion of a `Pro` role still exists (hopefully I got all of them, but please let me know if I missed anything! πŸ˜ƒ)

UI accessibility concerns?

No HTML or UX changes happens as a part of this PR, so I don't think so.

Added tests?

  • [ ] Yes
  • [x] No, and this is why: I've updated pre-existing tests and added new ones where necessary (but didn't overhaul the testing significantly enough IMO to check the "Yes" box πŸ˜‰)
  • [ ] I need help with writing tests

[Forem core team only] How will this change be communicated?

Will this PR introduce a change that impacts Forem members or creators, the development process, or any of our internal teams? If so, please note how you will share this change with the people who need to know about it.

  • [ ] I've updated the Developer Docs and/or Admin Guide, or Storybook (for Crayons components)
  • [ ] I've updated the README or added inline documentation
  • [x] I will share this change in a Changelog or in a forem.dev post (I will work with @cmgorton to make sure this is highlighted/announced to the community since we are sharing a feature that was previously only available to handful of folks!)
  • [x] I will share this change internally with the appropriate teams
  • [ ] I'm not sure how best to communicate this change and need help
  • [ ] This change does not need to be communicated, and this is why not: please replace this line with details on why this change doesn't need to be shared

Are there any post deployment tasks we need to perform?

After this feature is out, we will need to delete any Pro roles from the database. Even with the "pro" code all removed, the role still exists in the database, as evidenced by this screenshot of my local Forem instance, once I added the :pro role to my own user and deleted the "pro" code (seems like the Role instance still exists in the database): Screen Shot 2021-03-28 at 3 59 01 PM

I think that this only applies to the DEV community, but I'm not entirely sure about that and could use some gut checks there. My thought was to either write a DataUpdateScript (if this applies to many communities), otherwise maybe we can delete the :pro role directly via a DEV console?

A script would definitely be more comprehensive, but if no other Forem instance has pro roles, that feels much more heavyweight than we need it to be.

What gif best describes this PR or how it makes you feel?

animation of woman cutting bangs off with scissors

@-Mention Autocomplete

This PR adds autocomplete functionality for usernames. This feature is now available for both comments and posts.

You can read more about the component created for this feature and upcoming plans to use it in other areas of Forem in the post Changelog: Autocomplete for user mentions.

Add (updated) mention autocomplete to post comments #13061

What type of PR is this? (check all applicable)

  • [X] Feature

Description

This PR adds the @mention autocomplete component to:

  • Comments on a post
  • Replies to comments on a post
  • Replies to post comments in a notification

Related Tickets & Documents

RFC: Create Mention Autocomplete

QA Instructions, Screenshots, Recordings

This will need tested in each of the situations mentioned above, ideally on mobile devices as well as desktop to make sure all's working well.

Steps to test post comments:

  • Go to a post
  • Click to add a comment
  • Start typing, including some @mentions (you might want to add some users with similar usernames to your local DB to be able to see fuller lists appearing in the dropdown)
  • Experiment with selecting options with keyboard (up/down arrows + Enter) and mouse
  • Experiment with deleting portions of the mention, ignoring the options and keeping typing, etc - try to break it πŸ˜„
  • Repeat as above with replies to comments on a post

Video of these test steps:

https://user-images.githubusercontent.com/20773163/111762231-af286a00-8898-11eb-91ed-1d68a2bfa6fe.mp4

Steps to test post comment replies in notifications:

  • Send a notification to your current user in the console:
user = User.find_by(username: "admin_mcadmin")
other_user = User.first
article = user.articles.last
comment = article.comments.create!(user: other_user, body_markdown: "Test something")
Notification.send_new_comment_notifications_without_delay(comment)
  • Refresh the page and go to the notification
  • Click reply and repeat the above steps

Video of these test steps:

https://user-images.githubusercontent.com/20773163/111762257-b9e2ff00-8898-11eb-81fd-3510b52d3dc2.mp4

UI accessibility concerns?

This component should be operable by keyboard alone, and when using a screen reader, should announce the "combobox" functionality, and read the options in the dropdown when populated. This has largely been tested, and concerns documented in the previous PR #13044

Added tests?

  • [X] Yes

[Forem core team only] How will this change be communicated?

[optional] What gif best describes this PR or how it makes you feel?

David from Schitt's Creeks says yeah you've mentioned that a few times

Removed Mod Button on Mobile’s Top Navigation Bar

This PR removes the moderator button in the top nav bar that caused the profile menu button to be pushed off the screen on mobile if a community had a wide logo.

Remove mod button from top nav bar in mobile #12906

What type of PR is this? (check all applicable)

  • [x] Bug Fix

Description

Remove the mod button in the top nav bar, since it was causing a bug that pushed off the profile menu button in mobile.

Related Tickets & Documents

Resolves https://github.com/forem/internalEngineering/issues/393

QA Instructions, Screenshots, Recordings

Screen Shot 2021-03-04 at 3 11 31 PM

UI accessibility concerns?

Should be okay! Just added a link with nothing special about it.

Added tests?

  • [x] No, and this is why: I could add an e2e test but I'd rather not slow down this bug fix. Maybe in a separate PR.

[Forem core team only] How will this change be communicated?

  • [ ] Other: I will share this change with moderators in the appropriate Connect channels

[optional] Are there any post deployment tasks we need to perform?

Nope

[optional] What gif best describes this PR or how it makes you feel?

Three dudes go swoosh, and slide across the floor.

Optimize Finding Articles by Followed Tags

This PR improves the performance of searching for articles by the tags a user followed. It also paves the way for future optimization in more places where users search for articles by tags.

User#followed_articles->Article.cached_tagged_with #13174

What type of PR is this? (check all applicable)

  • [ ] Refactor
  • [ ] Feature
  • [ ] Bug Fix
  • [x] Optimization
  • [ ] Documentation Update

Description

This should improve performance on StoriesController#index.

On DEV, the mismatch between tagged_with and cached_tagged_with is at most 0.007% β€” the javascript tag, with 4 mismatches, the last of which was published over 3 years ago.

Running it for all the tags I could think of off the top of my head, I came up with 0 mismatches on all articles published within the last year:

articles = Article
  .published
  .where('published_at > ?', 1.year.ago)

%w[ruby javascript discuss meta elixir golang rust career performance].map do |tag|
  (articles.tagged_with(tag).count - articles.cached_tagged_with(tag).count).abs
end
# => [0, 0, 0, 0, 0, 0, 0, 0, 0]
Enter fullscreen mode Exit fullscreen mode

Added tests?

  • [ ] Yes
  • [x] No, and this is why: The existing tests should be sufficient to ensure the behavior has not changed
  • [ ] I need help with writing tests

[Forem core team only] How will this change be communicated?

Will this PR introduce a change that impacts Forem members or creators, the development process, or any of our internal teams? If so, please note how you will share this change with the people who need to know about it.

  • [ ] I've updated the Developer Docs and/or Admin Guide, or Storybook (for Crayons components)
  • [ ] I've updated the README or added inline documentation
  • [ ] I will share this change in a Changelog or in a forem.dev post
  • [x] I will share this change internally with the appropriate teams
  • [ ] I'm not sure how best to communicate this change and need help
  • [ ] This change does not need to be communicated, and this is why not: please replace this line with details on why this change doesn't need to be shared

Forem Loads on an Apple M1

This PR fixes an error while trying to load a Forem on a M1 Mac. You can read more about the error and how it was fixed in the PR description.

Update http-parser and ffi gems so Forem can load on an Apple M1 #13086

What type of PR is this? (check all applicable)

  • [ ] Refactor
  • [ ] Feature
  • [x] Bug Fix
  • [ ] Optimization
  • [ ] Documentation Update

Description

I was getting this error trying to load Forem on my M1 Mac:

<snip>/gems/ffi-1.14.2/lib/ffi/library.rb:145:in `block in ffi_lib': Could not open library '<snip>/gems/ruby-2.7.2/gems/http-parser-1.2.2/ext/aarch64-darwin/libhttp-parser-ext.bundle': dlopen(<snip>/gems/http-parser-1.2.2/ext/aarch64-darwin/libhttp-parser-ext.bundle, 5): no suitable image found.  Did find: (LoadError)
    <snip>/gems/http-parser-1.2.2/ext/aarch64-darwin/libhttp-parser-ext.bundle: mach-o, but wrong architecture
    <snip>/gems/http-parser-1.2.2/ext/aarch64-darwin/libhttp-parser-ext.bundle: mach-o, but wrong architecture

My Ruby installation was compiled for the M1:

➜  forem git:(master) file $(which ruby)
<snip>/ruby-2.7.2/bin/ruby: Mach-O 64-bit executable arm64

Updating http-parser updated the ffi gem, which fixes the bug on ARM Ruby.

Added tests?

  • [ ] Yes
  • [x] No, and this is why: the end result should be identical functionality
  • [ ] I need help with writing tests

[Forem core team only] How will this change be communicated?

If running Forem was broken for everyone using Ruby compiled for the Apple M1 before this, we may want to communicate that it can now run on an M1-compiled Ruby.

  • [ ] I've updated the Developer Docs and/or Admin Guide, or Storybook (for Crayons components)
  • [ ] I've updated the README or added inline documentation
  • [ ] I will share this change in a Changelog or in a forem.dev post
  • [ ] I will share this change internally with the appropriate teams
  • [x] I'm not sure how best to communicate this change and need help
  • [ ] This change does not need to be communicated, and this is why not:

[optional] Are there any post deployment tasks we need to perform?

Not unless we're deploying to boxes with ARM CPUs. πŸ˜„

[optional] What gif best describes this PR or how it makes you feel?

Pulling an M1 Abrams tank

Top comments (1)

Collapse
 
lee profile image
Lee

My favourite notification! I have tried @mentions in posts, very very cool!