I gave a talk at Rails World 2023 in Amsterdam on Powerful Rails Features You Might Not Know.
If all you've got is a hammer, everything looks like a nail. In tech, there is a constant stream of new features being added every day. Keeping up with the latest Ruby on Rails functionality can help you and your team be far more productive than you might normally be.
In this talk, we walk through a bunch of lesser known or easy to miss features in Ruby on Rails that you can use to improve your skills.
Código Saudável => Programador Feliz - Rs on Rails 2010Plataformatec
Palestra do Rs On Rails, na qual demos algumas dicas de boas práticas para manter seu código mais limpo e ter absoluto controle da sua aplicação em produção.
"Quem já trabalhou numa startup sabe como funciona o processo de desenvolvimento. "Faça rápido e no futuro a gente arruma." Acontece que quando o "futuro" chega, ele chega rasgando, te acordando de madrugada com notificações e com clientes reclamando. Nessa apresentação vou mostrar várias técnicas não muito difundidas para melhorar a performance do seu app escrito com Rails e fazer você dormir mais.
Código Saudável => Programador Feliz - Rs on Rails 2010Plataformatec
Palestra do Rs On Rails, na qual demos algumas dicas de boas práticas para manter seu código mais limpo e ter absoluto controle da sua aplicação em produção.
"Quem já trabalhou numa startup sabe como funciona o processo de desenvolvimento. "Faça rápido e no futuro a gente arruma." Acontece que quando o "futuro" chega, ele chega rasgando, te acordando de madrugada com notificações e com clientes reclamando. Nessa apresentação vou mostrar várias técnicas não muito difundidas para melhorar a performance do seu app escrito com Rails e fazer você dormir mais.
Application Security from the Inside - OWASPSqreen
Presentation at the OWASP (Open Web Application Security Project) on how to make apps secure by protecting them from the inside.
Detecting and protecting from
1. SQL injection
2. Cross Site Scripting (XSS)
3. Third party components vulnerabilities
4. Shell injection
etc.
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeAftab Hussain
Understanding variable roles in code has been found to be helpful by students
in learning programming -- could variable roles help deep neural models in
performing coding tasks? We do an exploratory study.
- These are slides of the talk given at InteNSE'23: The 1st International Workshop on Interpretability and Robustness in Neural Software Engineering, co-located with the 45th International Conference on Software Engineering, ICSE 2023, Melbourne Australia
Software Engineering, Software Consulting, Tech Lead.
Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Security,
Spring Transaction, Spring MVC,
Log4j, REST/SOAP WEB-SERVICES.
More Related Content
Similar to Rails World 2023: Powerful Rails Features You Might Not Know
Application Security from the Inside - OWASPSqreen
Presentation at the OWASP (Open Web Application Security Project) on how to make apps secure by protecting them from the inside.
Detecting and protecting from
1. SQL injection
2. Cross Site Scripting (XSS)
3. Third party components vulnerabilities
4. Shell injection
etc.
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeAftab Hussain
Understanding variable roles in code has been found to be helpful by students
in learning programming -- could variable roles help deep neural models in
performing coding tasks? We do an exploratory study.
- These are slides of the talk given at InteNSE'23: The 1st International Workshop on Interpretability and Robustness in Neural Software Engineering, co-located with the 45th International Conference on Software Engineering, ICSE 2023, Melbourne Australia
Software Engineering, Software Consulting, Tech Lead.
Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Security,
Spring Transaction, Spring MVC,
Log4j, REST/SOAP WEB-SERVICES.
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamtakuyayamamoto1800
In this slide, we show the simulation example and the way to compile this solver.
In this solver, the Helmholtz equation can be solved by helmholtzFoam. Also, the Helmholtz equation with uniformly dispersed bubbles can be simulated by helmholtzBubbleFoam.
Understanding Globus Data Transfers with NetSageGlobus
NetSage is an open privacy-aware network measurement, analysis, and visualization service designed to help end-users visualize and reason about large data transfers. NetSage traditionally has used a combination of passive measurements, including SNMP and flow data, as well as active measurements, mainly perfSONAR, to provide longitudinal network performance data visualization. It has been deployed by dozens of networks world wide, and is supported domestically by the Engagement and Performance Operations Center (EPOC), NSF #2328479. We have recently expanded the NetSage data sources to include logs for Globus data transfers, following the same privacy-preserving approach as for Flow data. Using the logs for the Texas Advanced Computing Center (TACC) as an example, this talk will walk through several different example use cases that NetSage can answer, including: Who is using Globus to share data with my institution, and what kind of performance are they able to achieve? How many transfers has Globus supported for us? Which sites are we sharing the most data with, and how is that changing over time? How is my site using Globus to move data internally, and what kind of performance do we see for those transfers? What percentage of data transfers at my institution used Globus, and how did the overall data transfer performance compare to the Globus users?
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisGlobus
JASMIN is the UK’s high-performance data analysis platform for environmental science, operated by STFC on behalf of the UK Natural Environment Research Council (NERC). In addition to its role in hosting the CEDA Archive (NERC’s long-term repository for climate, atmospheric science & Earth observation data in the UK), JASMIN provides a collaborative platform to a community of around 2,000 scientists in the UK and beyond, providing nearly 400 environmental science projects with working space, compute resources and tools to facilitate their work. High-performance data transfer into and out of JASMIN has always been a key feature, with many scientists bringing model outputs from supercomputers elsewhere in the UK, to analyse against observational or other model data in the CEDA Archive. A growing number of JASMIN users are now realising the benefits of using the Globus service to provide reliable and efficient data movement and other tasks in this and other contexts. Further use cases involve long-distance (intercontinental) transfers to and from JASMIN, and collecting results from a mobile atmospheric radar system, pushing data to JASMIN via a lightweight Globus deployment. We provide details of how Globus fits into our current infrastructure, our experience of the recent migration to GCSv5.4, and of our interest in developing use of the wider ecosystem of Globus services for the benefit of our user community.
Listen to the keynote address and hear about the latest developments from Rachana Ananthakrishnan and Ian Foster who review the updates to the Globus Platform and Service, and the relevance of Globus to the scientific community as an automation platform to accelerate scientific discovery.
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
Check out the webinar slides to learn more about how XfilesPro transforms Salesforce document management by leveraging its world-class applications. For more details, please connect with sales@xfilespro.com
If you want to watch the on-demand webinar, please click here: https://www.xfilespro.com/webinars/salesforce-document-management-2-0-smarter-faster-better/
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Globus
The Earth System Grid Federation (ESGF) is a global network of data servers that archives and distributes the planet’s largest collection of Earth system model output for thousands of climate and environmental scientists worldwide. Many of these petabyte-scale data archives are located in proximity to large high-performance computing (HPC) or cloud computing resources, but the primary workflow for data users consists of transferring data, and applying computations on a different system. As a part of the ESGF 2.0 US project (funded by the United States Department of Energy Office of Science), we developed pre-defined data workflows, which can be run on-demand, capable of applying many data reduction and data analysis to the large ESGF data archives, transferring only the resultant analysis (ex. visualizations, smaller data files). In this talk, we will showcase a few of these workflows, highlighting how Globus Flows can be used for petabyte-scale climate analysis.
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns
Unlocking Business Potential: Tailored Technology Solutions by Prosigns
Discover how Prosigns, a leading technology solutions provider, partners with businesses to drive innovation and success. Our presentation showcases our comprehensive range of services, including custom software development, web and mobile app development, AI & ML solutions, blockchain integration, DevOps services, and Microsoft Dynamics 365 support.
Custom Software Development: Prosigns specializes in creating bespoke software solutions that cater to your unique business needs. Our team of experts works closely with you to understand your requirements and deliver tailor-made software that enhances efficiency and drives growth.
Web and Mobile App Development: From responsive websites to intuitive mobile applications, Prosigns develops cutting-edge solutions that engage users and deliver seamless experiences across devices.
AI & ML Solutions: Harnessing the power of Artificial Intelligence and Machine Learning, Prosigns provides smart solutions that automate processes, provide valuable insights, and drive informed decision-making.
Blockchain Integration: Prosigns offers comprehensive blockchain solutions, including development, integration, and consulting services, enabling businesses to leverage blockchain technology for enhanced security, transparency, and efficiency.
DevOps Services: Prosigns' DevOps services streamline development and operations processes, ensuring faster and more reliable software delivery through automation and continuous integration.
Microsoft Dynamics 365 Support: Prosigns provides comprehensive support and maintenance services for Microsoft Dynamics 365, ensuring your system is always up-to-date, secure, and running smoothly.
Learn how our collaborative approach and dedication to excellence help businesses achieve their goals and stay ahead in today's digital landscape. From concept to deployment, Prosigns is your trusted partner for transforming ideas into reality and unlocking the full potential of your business.
Join us on a journey of innovation and growth. Let's partner for success with Prosigns.
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppGoogle
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-fusion-buddy-review
AI Fusion Buddy Review: Key Features
✅Create Stunning AI App Suite Fully Powered By Google's Latest AI technology, Gemini
✅Use Gemini to Build high-converting Converting Sales Video Scripts, ad copies, Trending Articles, blogs, etc.100% unique!
✅Create Ultra-HD graphics with a single keyword or phrase that commands 10x eyeballs!
✅Fully automated AI articles bulk generation!
✅Auto-post or schedule stunning AI content across all your accounts at once—WordPress, Facebook, LinkedIn, Blogger, and more.
✅With one keyword or URL, generate complete websites, landing pages, and more…
✅Automatically create & sell AI content, graphics, websites, landing pages, & all that gets you paid non-stop 24*7.
✅Pre-built High-Converting 100+ website Templates and 2000+ graphic templates logos, banners, and thumbnail images in Trending Niches.
✅Say goodbye to wasting time logging into multiple Chat GPT & AI Apps once & for all!
✅Save over $5000 per year and kick out dependency on third parties completely!
✅Brand New App: Not available anywhere else!
✅ Beginner-friendly!
✅ZERO upfront cost or any extra expenses
✅Risk-Free: 30-Day Money-Back Guarantee!
✅Commercial License included!
See My Other Reviews Article:
(1) AI Genie Review: https://sumonreview.com/ai-genie-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
#AIFusionBuddyReview,
#AIFusionBuddyFeatures,
#AIFusionBuddyPricing,
#AIFusionBuddyProsandCons,
#AIFusionBuddyTutorial,
#AIFusionBuddyUserExperience
#AIFusionBuddyforBeginners,
#AIFusionBuddyBenefits,
#AIFusionBuddyComparison,
#AIFusionBuddyInstallation,
#AIFusionBuddyRefundPolicy,
#AIFusionBuddyDemo,
#AIFusionBuddyMaintenanceFees,
#AIFusionBuddyNewbieFriendly,
#WhatIsAIFusionBuddy?,
#HowDoesAIFusionBuddyWorks
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Crescat
Crescat is industry-trusted event management software, built by event professionals for event professionals. Founded in 2017, we have three key products tailored for the live event industry.
Crescat Event for concert promoters and event agencies. Crescat Venue for music venues, conference centers, wedding venues, concert halls and more. And Crescat Festival for festivals, conferences and complex events.
With a wide range of popular features such as event scheduling, shift management, volunteer and crew coordination, artist booking and much more, Crescat is designed for customisation and ease-of-use.
Over 125,000 events have been planned in Crescat and with hundreds of customers of all shapes and sizes, from boutique event agencies through to international concert promoters, Crescat is rigged for success. What's more, we highly value feedback from our users and we are constantly improving our software with updates, new features and improvements.
If you plan events, run a venue or produce festivals and you're looking for ways to make your life easier, then we have a solution for you. Try our software for free or schedule a no-obligation demo with one of our product specialists today at crescat.io
Essentials of Automations: The Art of Triggers and Actions in FMESafe Software
In this second installment of our Essentials of Automations webinar series, we’ll explore the landscape of triggers and actions, guiding you through the nuances of authoring and adapting workspaces for seamless automations. Gain an understanding of the full spectrum of triggers and actions available in FME, empowering you to enhance your workspaces for efficient automation.
We’ll kick things off by showcasing the most commonly used event-based triggers, introducing you to various automation workflows like manual triggers, schedules, directory watchers, and more. Plus, see how these elements play out in real scenarios.
Whether you’re tweaking your current setup or building from the ground up, this session will arm you with the tools and insights needed to transform your FME usage into a powerhouse of productivity. Join us to discover effective strategies that simplify complex processes, enhancing your productivity and transforming your data management practices with FME. Let’s turn complexity into clarity and make your workspaces work wonders!
4. ActiveRecord Strict Loading
class Project < ApplicationRecord
has_many :comments, strict_loading: true
end
project = Project.first
project.comments
ActiveRecord::StrictLoadingViolationError
`Project` is marked as strict_loading. The Comment association named
`:comments` cannot be lazily loaded.
5. ActiveRecord Strict Loading
project = Project.includes(:comments).first
Project Load (0.3ms) SELECT "projects".* FROM "projects" ORDER BY
"projects"."id" ASC LIMIT ? [["LIMIT", 1]]
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE
"comments"."project_id" = ? [["project_id", 1]]
=> #<Project:0x00000001054af780 id: 1>
project.comments
=> [#<Comment:0x00000001054aed80 id: 1, project_id: 1, body: "Hello
RailsWorld">]
6. Generated Columns
class AddNameVirtualColumnToUsers < ActiveRecord::Migration[7.0]
def change
add_column :users, :full_name, :virtual,
type: :string,
as: "first_name || ' ' || last_name",
stored: true
end
end
8. with_options
class Account < ActiveRecord::Base
with_options dependent: :destroy do
has_many :customers
has_many :products
has_many :invoices
has_many :expenses
end
end
36. truncate_words
content = 'And they found that many people were sleeping better.'
content.truncate_words(5, omission: '... (continued)')
# => "And they found that many... (continued)"
38. Time.current.all_day
#=> Fri, 06 Oct 2023 00:00:00 UTC +00:00..
Fri, 06 Oct 2023 23:59:59 UTC +00:00
Time.current.all_week
#=> Mon, 02 Oct 2023 00:00:00 UTC +00:00..
Sun, 08 Oct 2023 23:59:59 UTC +00:00
Time.current.all_month
#=> Sun, 01 Oct 2023 00:00:00 UTC +00:00..
Tue, 31 Oct 2023 23:59:59 UTC +00:00
Time Helpers
53. authenticate_by
class User < ApplicationRecord
has_secure_password
end
User.find_by(email: "chris@gorails.com")
&.authenticate(“railsworld2023")
#=> false or user
User.authenticate_by(
email: "chris@gorails.com",
password: "railsworld2023"
) #=> user or nil
56. generates_token_for
class User < ApplicationRecord
generates_token_for :password_reset, expires_in: 15.minutes do
# BCrypt salt changes when password is updated
BCrypt::Password.new(password_digest).salt[-10..]
end
end
59. Named variants
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumbnail,
resize_to_limit: [200, 200]
end
end
60. Preprocessed variants
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumbnail,
resize_to_limit: [200, 200],
preprocessed: true
end
end
When all you’ve got is a hammer, everything looks like a nail.
You have a task and end up in the weeds to figure out a solution. Next time you come across a similar problem, you jump straight into the weeds remembering your solution from last time even though there may be better tools available to you this time around.
So the goal of this talk is a reminder to learn and master the tools you have available.
Let’s start off with a simple example.
Say you’re sending notifications for a conversation thread. Something like a GitHub issue.
Rails 7 added the excluding method to ActiveRecord.
By using excluding, we can think about the problem at a higher level instead of thinking on a SQL level.
Another example of this is strict loading. This was introduced in Rails 6.1 and helps prevent N+1 issues without any external dependencies.
ActiveRecord queries will now raise a Strict Loading error when you query an association that’s marked as strict_loading.
To do this properly, we can grab the project but eager load comments using includes(:comments).
This will load the project and the comments into memory
And when we ask for the project comments, we get the list of comments with no error this time.
Generated columns allow you to create a column computed from other columns in your database.
For example, we can make a “full name” column that is a combination of first and last name. Or calculate price_in_cents from a decimal price (or vice versa).
By using the “stored”, the column is computed when it’s written and is saved in storage like a normal column. When stored: false, it’s a virtual column that’s computed when read.
Generated columns were added to the PostgreSQL adapter in Rails 7 and has been supported in MySQL for a while and SQLite support is coming.
attr_readonly is another handy feature in ActiveRecord. We can still create a new user with super_admin set to true or false, but after that ActiveRecord cannot change the super_admin attribute.
Even update_column which skips validations and callbacks still verifies the readonly attributes.
with_options is a feature of ActiveSupport that lets you define options you want to include in every method call in the block.
Here we have 4 associations and all of them need dependent: :destroy, so we can use with_options to add that for every association.
You can also use with_options like this where we call it on the I18n class.
The i18n translate calls here get the locale and scope applied automatically.
The safe navigation operator in Ruby is amazing, but it doesn’t help in every situation.
Let’s say you want to call a method if an object responds to it.
This gets more complicated when we want to have a fallback.
Try lets us do this cleanly and it reads extremely well.
Another undervalued feature of Rails is ActionText. Sure, it format text, but the real magic is in embedding records from your database.
Here, you can see ActionText with a User record mentioned in it. When my name or avatar changes, the text renders with the new content.
You could also use this to embed YouTube videos, Twitter and Instagram posts.
The first step for embeds is asking the server for the embed data. The server will need to return a Signed GlobalID (SGID) and HTML preview for each user suggested.
A signed global ID looks like this. It’s a base64 encoded string with a signature at the end after the double hyphens. We’ll explore this more in a second.
When the user selects one of these entries, we can take the SGID and HTML preview on the client side and insert it into the Trix editor.
If I select myself here…
The JavaScript creates a new Trix Attachment using the HTML content and SGID and then inserts it into the editor.
Rails saves this to the database and it looks like this. We have an action-text-attachment element, but you’ll notice that it’s an empty tag. The HTML content is missing.
That’s because every time Rails renders this, it will look up the attachable (in this case, a User) and re-render the HTML content. This is what gets you the latest avatar and name every time it’s rendered.
When rendering, Rails looks at that Signed Global ID and finds the associated record.
Since these are Base64 encoded, we can decode them and you’ll see it’s a simple JSON message. It contains an expiration and purpose.
The message itself is also Base64 encoded.
If we decode the message, we’ll see that it is a regular Global ID that references a User model with the ID of 1 in our Jumpstart Pro app.
These signed Global IDs can also be extremely handy for building a polymorphic select box that allows you to choose a record from any model.
So here’s what our final result looks like. When we render our ActionText body, it finds each attachment and renders the partial for each associated record.
When my name or avatar changes, the next render will include the latest data.
A cool trick that ActionText uses internally is serializing with a custom coder.
Normally, we use Serialize to convert a Ruby hash to and from JSON or YAML. But you can use this to load and dump any object like ActionText does here.
To build a custom coder, all you need are the load and dump class methods. Here’s a simplified version of what ActionText does.
It simply creates a new Content object with the HTML and dumps the HTML back to the database while handling nil appropriately.
ActionMailbox is another favorite feature of mine that doesn’t get enough love.
Have you ever noticed the “via email” on GitHub issues and PRs?
You can implement something like this in Rails using ActionMailbox.
To do this, you’ll need to wire up ActionMailbox to your email provider. They will convert incoming emails to webhooks that are sent to your Rails application.
Inside ApplicationMailbox, you’ll define routings that match against the sender’s email address. Here, we’re taking anything @replies.domain.com and sending it to the replies inbox.
The replies inbox implements a process method that takes the email and creates a new post for the conversation using the sender’s email address and body of the email.
We can look up the right conversation by embedding the ID in the email address and parsing it out with a little regex.
Routing constraints let you define routes that are available depending on details in the request.
For example, this constraint says to send the root route to the dashboard controller if the user is on the app subdomain. Otherwise, we’ll use the marketing site homepage for requests with say www or no subdomain.
Routing constraints have access to the request and the session so you can do some cool things with it.
Devise provides some custom routing helpers too. Authenticated is a helper method that checks if the user is authenticated and then draws routes accordingly.
If you’re logged in and have the admin flag, you can access /admin
If you’re logged in, your root path will be the dashboard.
And if you’re not logged in, we’ll show you the homepage.
Fun fact, 11 years ago I contributed part of this feature to Devise and was one of my first open source contributions.
Another handy routing feature is “draw”.
Draw lets you organize routes into separate files.
If we say “draw :api”, the config/routes/api.rb file will be evaluated.
This is super handy to organize API or Admin routes separately. Or if you’re building a marketplace that has a separate storefront and backend areas.
Rails also lets you build your own generators.
In Jumpstart Pro applications, we provide an API client generator. Instead of adding another dependency, you can generate an API client by running rails g api_client and give it a name.
Of course, Rails provides a generator for generating generators so you can run “rails generate generator name” and it will generate a generator.
Templates get evaluated with Erb, so you can use Ruby to generate a Ruby file dynamically just like how the Scaffold generator creates controllers, models, and views.
On the fronted, we can customize Turbo by adding our own Turbo Stream Actions.
Let’s say you want to send a browser notification from Rails.
Turbo Streams are a simple HTML element that have an action attribute that maps to a JavaScript function on the client side. The server just needs to tell it which action to perform and provide any other attributes or HTML to render.
We can use the turbo_stream_action_tag helper to generate this HTML element. This can be in a response from an HTTP request or broadcasted through Redis from a background job.
Once the element is inserted into the body of the page, the JavaScript finds the matching Turbo StreamAction and executes it.
To send our notification, we can ask the browser if we have permission to send a notification and, if granted, we can create a new notification with the title from the attribute.
And then you’ll see a fancy notification in your browser.
There are countless methods in ActiveSupport, but truncating text is another common thing we need.
I learned about “truncate” years ago and have used it ever since, but truncate works by character count. The problem is this will often stop in the middle of a word and isn’t as nice as a user.
Only recently did I learn that truncate words exists. We can specify how many words we want to display and even customize the “omission” parameter to say “dot dot dot continued”.
It always takes me a second to process time comparisons when I read them. starts_at is less than Time.current, so that means we’re asking if starts at before the current time.
Rails 6 added before? And after? Helpers that alias less and greater than for making time comparisons easier to read at a glance.
You can also use past? And future? To make this even quicker to read at a glance.
ActiveSupport also provides time helpers for generating ranges.
all_day will take the given date and return a range from the beginning of the day to the end of the day.
all_week does the same but for the week the date is in. It also can be configured for weeks to start on Sunday or Monday. This example shows weeks starting on Mondays.
all_month does the same but for the month
Matt Swanson posted this on Twitter a little while back and I thought his solution was another great example of taking advantage of the tools Rails gives you.
In the case of small numbers, we want to display them with commas.
For numbers larger than ten thousand, we want to abbreviate them to the nearest scale like thousands, millions, billions.
In the past, I would jump right into implementing this from scratch, but as we’ve learned…
Rails ships with the number_to_human helper. It takes a number and outputs the number with the human scale at the end.
The actual implementation is in ActiveSupport, but exposed as an ActionView Helper to use in your Rails views.
This is almost what we want, but we need to figure out how to abbreviate this.
Precision lets us control how rounding works and significant: false tells it to use the precision number for fractional digits instead of significant digits.
So here’s how we can implement abbreviated numbers using the tools Rails gives us
Return the number with delimiter if it’s less than ten thousand
For larger numbers, we want number to human version with some configuration
If we set precision to 1 and significant: false, we get 1 number after the decimal place.
We want to round down so we don’t accidentally inflate our numbers
Setting the format allows us to remove the default space between the number and the unit
And last but not least, we can just replace the long unit names with abbreviations like K, M, and B.
All that without any custom logic, rounding or anything!
So here’s how we can implement abbreviated numbers using the tools Rails gives us
Return the number with delimiter if it’s less than ten thousand
For larger numbers, we want number to human version with some configuration
If we set precision to 1 and significant: false, we get 1 number after the decimal place.
We want to round down so we don’t accidentally inflate our numbers
Setting the format allows us to remove the default space between the number and the unit
And last but not least, we can just replace the long unit names with abbreviations like K, M, and B.
All that without any custom logic, rounding or anything!
Rails 7.1 also adds strict locals. If you add this magic comment to the top of your templates, we can require the “message” local to be passed in a s a local.
Default values are also supported, so here we can set “Hello” as our default message.
You can also define a partial that takes no locals by using empty parentheses.
Normalizes is another feature I’m excited about. When users input something like an email address, we need to clean it up by removing whitespace and downcasing it.
The best way to do this until now has been overriding the setter method so that it’s normalized as soon as the value is assigned. We also have to safely handle nil values and it has always felt a bit messy.
In Rails 7.1, we can replace that with a call to normalizes. By default, nil values will be skipped so we can simply call strip and downcase without any safe navigation.
This reads a little redundant so we can also use Ruby’s numbered parameters to simplify this using _1.
Authenticate_by allows you to authenticate a user while preventing timing attacks. It will query the database for the User and load it into memory if it exists. If it doesn’t, your HTTP request may return measurably faster allowing attackers to figure out if you have an account with this email or not.
Authenticate_by mitigates this by instantiating a User in memory if one is not found so the timing in either case is virtually the same.
Password_challenge has been added as well. This is useful for verifying the current password before changing it to a new password.
with_defaults is another ActiveSupport goodie that is an alias for reverse_merge that lets you set default values in a hash.
This makes sure that password_challenge is always set to a value, even if a crafty user tries submitting the form without a password_challenge.
generates_token_for lets you generate tokens that don’t need to be stored in your database. These are signed using ActiveSupport MessageVerifier and can include an expiration and embedded data.
If you embed data using a block, this will be matched when the token is used and allows you to make one-time use tokens. If we successfully update our password, the salt changes and attempting to use the token again will fail because the salts no longer match.
To generate a token, we get the “generate_token_for” method which takes the token name.
To use the token, we can call find_by_token_for and give it the name and token value.
I’ve you’ve used ActiveStorage, you’ve probably added variant code all over your views and/or helpers.
Rails 7.0 introduced named variants which allow you to replace these resize and other calls with a name (just like you would do with scopes!)
Rails 7.1 introduces preprocessed variants. If we slap proprocessed: true on our named variant, a TransformJob will run automatically on after_create_commit