Ruby on Rails is a web framework heavy on conventions over configuration. All else equal we should try to follow Rails convention. We are currently on version 5.2.3, due for an upgrade to 6.x.x.
current_user. A page is edge-cached through our CDN Fastly if the controller contains this line for the relevant action...
We also user server-side caching Rails caching. Any time you see
<%= cache ... %>, this is code affected in production by caching.
To avoid blocking initial render, we put critical path CSS inline in the HTML and we user
The biggest element of technical debt in our app are mostly on the frontend. We use both "old" (in the assets folder) and "new" (in the
We also have a sprawling CSS structure with few consistent rules.
The home feed is based on a combination of collective recent posts that are cached and delivered the same to everyone in the HTML, and additional articles fetched from an Algolia index after page load. To determine which posts a user sees, they are ranked based on the user's followed tags, followed users, and relative weights for each tag. Additional fetched articles also follow this general pattern.
Currently, the top post on the home feed, which must have a cover image, is shared among all users.
DEV uses a variation of "instant click" which swaps out content instead of full page requests. It is similar to the Rails gem Turbolinks, but more lightweight. The library is modified to work specifically with the Rails app, and does not swap the nav bar or footer when a page is changed. The code for this functionality can be found in
window.InstantClick.on('change', someFunction). This means lines like this exist in the app...
initPreview(); window.InstantClick.on('change', initPreview);
This can change how variables need to be defined in certain contexts and orders, differently than if they were loaded freshly, or within the context of a truly integrated single page app.
Of course, it would be possible to abstract away some of these gotchas in the future.
This is the main high level content a user creates. An Article has many comments, taggings through acts-as-taggable gem, belongs to a user (and possibly an organization), and is generally the central core unit.
Comments belong to articles (or podcasts, generally polymorphic). They belong first and foremost to the user in our architecture, which is reflected by the URL (
/username/tag-slug) but they also fit in communal areas below other content. They are threaded but flatten out so that there is not infinite threading (e.g. once a discussion branch gets going, no more branching after a few).
Tags help organize content, with rules for each tag. A tag is a de facto community with one or more moderators with privileges to determine what is appropriate for the tag. Some tags act as "flare" for posts so they show up more pronounced in the article when viewed from the index. Tags that belong as "flare" are currently defined in the
FlareTag object. In cases of multiple flare tags, the flare displayed is determined by its hierarchy.
Classified listings are similar to posts in some ways, but with more limitations. They are designed to be categorized into market areas. They also make use of tags.
Users can belong to organizations, which have their own profile pages where posts can be published etc. This can be any group endeavor such as a company, an open source project, or any standalone publication on DEV
This is far from a complete view of the app, but it covers a few core concepts.