Welcome to another edition of This Week in #dev, a series of posts where we bring some of the most interesting Slack conversations to the public. Today we’re talking about: splitting arrays, handling deprecation warnings, and querying missing records.
A Handy Method for Splitting Enumerables
Steve Polito learned about Ruby’s Enumerable#partition
. This method is useful for
dividing an existing array into two separate arrays, he says.
# Before
def call(appointments)
appointments_today = []
appointments_next_week = []
appointments.each do |appointment|
if appointment.starts_at.to_date == Date.current
appointments_today << appointment
else
appointments_next_week << appointment
end
end
end
# After
def call(appointments)
appointments_today, appointments_next_week = appointments.partition do |appointment|
appointment.starts_at.to_date == Date.current
end
end
Handling Ruby Deprecation Warnings
Neil Carvalho discovers that Ruby deprecation warnings have been disabled
since Ruby 2.7.2 due to an excessive number of deprecation warnings related to
keyword arguments. This concerns him, and he suggests setting
Warning[:deprecated]
to true
in spec_helper.rb
and asks for other
suggestions.
Summer ☀️ steps in and proposes logging warnings to an error-tracking service in production, while in development and testing, they recommend raising errors instead of relying on log messages that can be easily overlooked. It would be also important to be able to choose whether these actions apply to project code or dependencies, and selectively silence specific deprecation types or downgrade them from errors to warnings.
Querying Missing Associated Records
Rémy Hannequin seeks assistance with an ActiveRecord query to retrieve records that are missing associated records with a specific attribute. He provides an example scenario of authors and books with different languages and wants to find authors who don’t have books written in Elvish:
# This is not what Remy wants
Author
.where.missing(:books)
.where(books: {language: :elvish})
# That generates this SQL
SELECT * FROM "authors"
LEFT OUTER JOIN "books" ON "books"."author_id" = "authors"."id"
WHERE "books"."id" IS NULL
AND "books"."language" = "elvish"
Neil Carvalho responds with two possible approaches. If it makes sense to define
a specific association for Elvish books in the Author
model, Neil Carvalho
suggests using Author.where.missing(:elvish_books)
to query authors without
associated Elvish books.
class Author
has_many :elvish_books, -> { where(language: "elvish") }, class_name: "Book"
end
# Now this works!
Author.where.missing(:elvish_books)
If it doesn’t make sense to define a separate association, the recommendation is using a left join:
Author.left_joins('books ON books.author_id = authors.id AND books.language = "elvish"')
Thanks
This edition was brought to you by Neil Carvalho, Rémy Hannequin, Steve Polito, and Summer ☀️. Thanks to all contributors! 🎉