Rails Tricks

Archive

02 May

Active Record where tricks - Rails Tricks Issue 5


Hey, this week, I am bringing you Active Record tricks to find records with missing associations or with associated records only, and to negate your conditions.


The first three methods I will cover are all implemented in ActiveRecord::QueryMethods::WhereChain, which acts as a placeholder object for where queries with no direct parameter.


The first method is associated, which generates an inner join SQL query with a NOT NULL condition on the join field. For instance, if you want to find all blog posts in your database with an author, you can achieve it with the following code:

90f9687b-2dd5-41c9-bb97-77366564f0aa.png 64.8 KB

The next method is missing, which does the opposite and returns the records with missing associations:

d31fc9b5-5467-466b-a10a-12d2c9926cc8.png 65 KB

It is worth nothing that you can specify multiple associations to both methods, so if you would want to find all posts where the author is missing and has zero comments, you can do so by calling Post.where.missing(:author, :comments) or if you want to find all posts where the author is set and has at least one comment, you can call Post.where.associated(:author, :comments).


The third method I want to mention is not, which can be used to negate a where condition:

eb28e1b6-5d99-44ec-859c-3b9cae841233.png 40.7 KB

There is also the not so well-known invert_where method, which inverts the previous where condition. So you can do this:

84dce8fe-93b7-44b3-82da-e2b14c8e95a0.png 46.9 KB

You can also use it when you define scopes to not duplicate your conditions:

9498390e-4bc3-4ec7-91e8-f65d19bdab7b.png 60.5 KB

That’s it for this week!

25 Apr

Active Support helpers configuration - Rails Tricks Issue 4


Hi, this week I am bringing you a trick to configure Active Support helpers!


Active Support is a collection of utility classes and extensions to Ruby core and standard library classes. It provides quite a few valuable data formatting helpers, and if you want to change their formatting settings globally, you can do so by utilizing Rails’ localization.


One such a helper is number_to_currency, which takes precision, unit, delimiter, format, negative_format, and strip_insignificant_zeros as options when you call the helper. If you want to strip insignificant zeros globally, instead of passing the same option over and over to the helper in your code, you can just change the option in your locale file:

f892d2c5-bed1-4f4b-8688-b0d2b3cb8c43.png 44.9 KB

There is also the number_to_human_size helper, which has delimiter, precision, significant, and strip_insignificant_zero options. You can change those globally in the locale file too:

628fc3ff-eb58-40a2-8e33-b7383bbbf4f3.png 139 KB

Dates are also often formatted into specific formats within an application by calling to_s(:date_format), which is deprecated now in favor of to_fs(:date_format). If you want to use a custom format, you can do so in the locale file:

4d09ad69-0652-4d49-85aa-dffce2b27f20.png 94.2 KB

You are probably working with DateTime objects too in your app, so it is a good idea to set the same formats for Time too:

dc1735e2-0d81-4d02-b165-91991a345063.png 71 KB

Last week, I mentioned the Array#to_sentence helper, which can be configured globally from the locale file too:

53f83c5b-7500-40db-bf69-fb9e39bce3c2.png 66.7 KB

That’s it for this week. Until next time!

18 Apr

Array Tricks - Rails Tricks Issue 3


Hi, this is your weekly Rails Trick!


This time, I am bringing a few Active Support extensions on Array.


The first one is the to_sentence conversion method. By default, it converts the array to a comma-separated list of words, with the last element joined by “and”. For example:

a3589f39-0ec6-476e-82fe-d93d696e6d98.png 19.8 KB

You can specify the words_connector and the last_word_connector if you want to use something other than the comma and “and”:

d4371ed1-cbb5-435b-bf99-d5e373b694bc.png 48.5 KB

The next extension I want to mention is the ArrayInquirer. By calling inquiry on an array, you can convert it to an ActiveSupport::ArrayInquirer object. This will give you predicate methods on the string-like contents of the array. For example:

fb54923c-a11b-482f-b80a-d943f88717af.png 73.5 KB As a side note, Rails uses this internally for the variant predicates in Action Dispatch.

Active Support
also adds a few extra access methods to Array. There is from, which takes a position and returns the tail of the array from that position. There is to, which does the opposite and returns the beginning of the array up until the given position.


There is also the including method, which returns a new array including the elements passed to it. and you can achieve the opposite with excluding, which returns a new array excluding the elements passed to the method. excluding is actually implemented on Enumerable in Ruby, but Active Support reimplements it on Array to make it more performant. It is also worth mentioning that excluding is aliased as without.


There are also methods to access, second, third, fourth and the fifth elements of an array. And there is fourty_two, which has an interesting history. Back in the day, we had these helpers up till 10 (if my memory serves me well), and some people were complaining about them, saying they are bloating Active Support. As a response to the criticism, fourty_two was added as a kind of joke to access “the reddit”, implicating that it holds the Ultimate Answer to Life, the Universe, and Everything .


That’s it for this week!

11 Apr

Rails Tricks Issue 2: Console Tricks


Hi, this is Greg with the second issue of Rails Tricks!


Thanks to everyone for subscribing!


This week, I want to share a few Rails console tricks I use regularly. The first one is the _ command, which always holds the return value of the last evaluated command in IRB, which is the default for Rails` console. For instance, if you run an Active Record query to find a record, then you realize that you want to keep the result around, you can easily assign it to a variable:

39f85102-9d90-419a-9421-092d9fdd535a.png 84.5 KB

Another thing I regularly do is, to look up the definition of methods or the location of their definition. This comes in handy when you are debugging an issue and can be helpful to see what a method actually does or where it is defined. 
Because maybe a gem overrides it, and that causes unexpected behavior. In a Rails console, to see the definition, you can use Object.method(:name).source:

3a342bd2-e713-41a2-b113-22ef6f36dd50.png 102 KB And if you want to verify that all is defined in Active Record and nothing overrides it in your application, you can check the location of the definition: e0c5a374-e943-44e7-ae68-1722e434bc56.png 96.4 KB The source method is actually added by a gem called methodsource, which was part of Rails between 7.1, but it will be removed with that release, so if you still want to be able to see the definition of methods in your console, you will need to add that gem to your Gemfile.

The next thing I want to share is the --sandbox option. If you pass this option when you start your console, every database modification will be rolled back on exit. 
This can be useful when you are debugging something in production, and you want to make sure you are not messing up something accidentally.


And the final thing is to have some fun! Type IRB.send(:easter_egg, :dancing) or IRB.send(:easter_egg, :logo) in your IRB session and enjoy the result!
You can exit by pressing CTRL+C.


P.S.: I just came across this blog post recently from Jemma about the measure command in IRB: https://jemma.dev/blog/irb-measure.


This week I have a special guest trick:


Hello there, I'm
Adrian, the author of Avo, and I'm excited to share a neat trick with you today. In this tutorial, I'll be demonstrating how to attach hooks and business logic to Avo's controllers using a Current model.


You may already be familiar with
Rails' Current model, which is used to set the current user, multi-tenancy accounts, or other pieces of information. Typically, before_action is used in your ApplicationController to demonstrate how Current works. However, if you attempt to apply the same changes to your app the action will not work in Avo's context. This is because Avo has its own AplicationController.


So how do we apply this behavior inside Avo? Let me walk you through it.


Firstly, we configure the
Current model and create the concern that holds the business logic.

4d4a88e0-a863-4a4c-af1d-cfb7581957a9.png 149 KB Next, we add this concern to Avo's ApplicationController using Rails' to_prepare hook: 29c47f32-3ebd-4107-a264-30c5acf7ddee.png 53.3 KB With this setup, our Authentication concern will be applied to the Avo::ApplicationController, and it will be executed within Avo's context.

This technique can also be applied to other classes, such as including all helpers inside Avo's field declarations:

ff4fdf89-8e21-4b8a-aeab-52489c8747d2.png 183 KB By following these steps, you can now use your own extensions in your Avo resources. I hope this short tutorial helps you write better Avo resources and ship code faster.

Adrian ✌


That’s it for this week, see you next time!


Greg

04 Apr

Rails Tricks Issue 1


Hi, this is Greg, bringing you the first edition of the Rails Tricks newsletter.


Thank you for subscribing! I hope you will learn a few things over time.


Let me explain what I consider a "Rails Trick". For me, these are the not so well known features of Rails/Ruby.


Let's see our first one.


I am bringing you a view layer trick this week. We will be looking into conditionally rendering links. Rails has a link_to helper to generate links, but there are not such well-known similar helpers. For instance, there is link_to_if, to conditionally render a link:

bca15b8f-3eb1-4dfe-80f5-232ad53366df.png 56.4 KB

It takes a condition for the first param, the name for the link as the second, and the options to construct the URL as the third. There is also an optional fourth argument to set HTML options for the link.


This helper has a counterpart, link_to_unless, which is the same, except it creates the link if the condition is false.


And there is link_to_unless_current. It takes the name for the first argument, the options to construct the URL as the second, and the optional HTML options as the third. But it only renders the link if the current request URI is not the same as the URL of the link. It can be handy when you don't want to have a link to the current page in your navigation bar.


As I mentioned, I will also try to share a non-Rails trick every week, and the first one will be a vim trick.


Vim has many lesser-known features, for instance, it has a built-in spell-checker. So if you are writing content in vim as I do, it can help to catch spelling mistakes. To enable it, enter vim set spell into the command bar.


That's it for now, see you next week!