Benito Serna Blog
7 FOLLOWERS
Tips and articles for Ruby on Rails developers
Benito Serna Blog
3M ago
I was reading about shoes.rb and, while scanning the book and walkthrough, I discovered a pattern that caught my attention for its power and simplicity.
The combination of “stacks” and “flows” allows you to build complex layouts, like the following example in Ruby:
Shoes.app do
background "#EFC"
border("#BE8", strokewidth: 6)
stack(margin: 12) do
para "Enter your name"
flow do
edit_line
button "OK"
end
end
end
What are a stacks and a flows?
A stack places one thing on top of another, similar to blocks in HTML.
A flow arranges items next to each other on a ho ..read more
Benito Serna Blog
3M ago
I have already shared a way of implementing a “read-more” behavior truncating by the number of lines instead of the number of words.
But now I want to share how you can do it using the line-clamp css property.
The example
Visit example page
The html and css
Your are going to need…
A linesValue to configure the number of lines that we want to display,
A class to hide the buttons and a class to truncate the content…
3 targets, the content, the moreButton and the lessButton…
3 actions
resize@window->read-more#render - to calculate the truncation on rezise.
click->read-more#showMore
click ..read more
Benito Serna Blog
9M ago
N+1 queries are not always a problem, but I have seen that most of the n+1 queries that are really a problem are when we need to fetch data to compute something.
Here I will try to share some examples of posible expensive computations candidates to be cached and some patterns that you could use to save different kind of values.
Some examples of possible expensive computations
I think the most common computation in many apps will be a count. It is that common that rails already have “counter caches”.
But sometimes you will need to save counts where a counter cache won’t be enough, like:
Counts ..read more
Benito Serna Blog
9M ago
There are many tools that can help you detect n+1 queries in different ways.
This is a little reference of some of those tools:
Strict loading
Rack mini profiler
Bullet
Prosopite
n plus one control
You don’t need to use all of them, but is good to know that they exists and how they can help you.
Rails strict_loading How it can help you?
You can add #strict_loading! to any record to prevent lazy loading of associations. Strict loading will cascade down from the parent record to all the associations to help you catch any places where you may want to use preload instead of lazy loading.
On a re ..read more
Benito Serna Blog
11M ago
Imagine that you want to truncate a filename, but you want to keep showing the extension of the file. Like “A big file name that…awesome.pdf”. How would you do it?
The omission parameter
With the :omission string the last characters will be replaced (defaults to “…”) for a total length not exceeding length:
string = "And they found that many people were sleeping better."
string.truncate(25, omission: '... (continued)')
# => "And they f... (continued)"
So, you can pass as the omssion string, the last characters of your string like this:
filename = "And they found that many peopl ..read more
Benito Serna Blog
11M ago
Imagine that you are building a custom CMS. Within the form to edit an Article, you need to have two buttons: a normal “Save” button and a new “Save and publish” button. And maybe, additionally, you will need a third button to delete the article.
To achieve this, you can use the formaction and formmethod attributes.
Changing the action with formaction
To add the “Save and publish” button, use the formaction attribute to override the action in the form:
<%= form_with model: article do |form| %>
...
<%= form.button "Save" %>
<%= form.button "Save and publish", formaction: s ..read more
Benito Serna Blog
11M ago
Imagine that you have a form to update a record (let’s say a product record) and inside the form, you are showing a list of images, and each image needs a button to remove it. You tried to use button_to but it doesn’t work because in html you can have form within a form. What do you do?
You can use the “form” attribute
You can use a button tag and define its form attribute. The value should be the id of a form located anywhere in the document.
For example, in the next code, for each persited image, we call render a button with a form attribute “delete_image_#{image.id}”.
<%= form_with(mode ..read more
Benito Serna Blog
11M ago
If you want to add images to a record but you don’t want to use a JavaScript plugin or write any custom JavaScript, you can use a regular file field, Active Storage, and vanilla Rails.
If you want to be able to:
Attach many images on create
Keep adding many images on every update
Display the images in a gallery
Be able to remove the images one by one
Here is a tutorial to help you accomplish that.
Example: A product with many attached images
To use as an example for the tutorial, we are going to have a Product record that has many attached images like this:
class Product < ApplicationRec ..read more
Benito Serna Blog
1y ago
If you want to add many attachments to a record using just a file field, but you don’t want to remove the previous images from the record on every update, like in the following code:
<%= form_with(model: product) do |form| %>
<%= form.label :images %>
<%= form.file_field :images, multiple: true %>
<%= form.submit %>
<% end %>
And instead, on every update you want to add the new images to the record, here is a simple workaround…
A virtual new_images attribute
Instead of using the :images attribute, you can add a virtual :new_images attribute, using an a ..read more
Benito Serna Blog
1y ago
When saving computed values in the database in your rails app, you must be aware that is possible to find unexpected errors in the result thanks to race conditions.
I have already shared an exercise to help you get more sensitivity about when an implementation can save a wrong value thanks to race conditions.
Here I want to share one tip to help you avoid save the wrong value due race conditions while trying to save a computed value.
Using the account balance as an example
To talk about something concrete I will use the “account balance” as an example, but you can use this appro ..read more