If you found yourself on this page then you are probably learning about ActiveRecord and Macros. ActiveRecord is essential to working in Rails after you learn the fundamentals of Ruby. By following the MVC (Models, Views, Controller) layout that Rails follows Macros become in integral part of this layout. One of the first question you must ask yourself when trying to understand any new material is “What is it?”. A macro is simply described as “ a class method which gives us instance methods”. For this explanation I will be using a simple Rails application I completed that uses three models with one of those models being a joiner. A joiner class simply establishes a relationship through two other models that otherwise would not be connected to each other. Below you will see the the three models with the Macros listed. For simplicity we are only using three different kinds of Macros to show how these work. You will notice that I laid out the models to reflect my domain layout with the joiner being in the middle because it is what is establishing our relationships throughout the other two models.
You can see that the three macros we are using are has_many, has_many through: , and also belongs_to. With these three models here we now have the ability to call instance methods on the other classes which we normally would not have access to. This is the “magic” that many people tend to say exists when using Rails. It is not magic but just the Macros creating and establishing relationships which gives us the instance methods. To show the simplicity of this we will be using the seed file I created when we made the app.
Now that we have the Macros set and established we can start to see the benefits of the instance methods that are provided to us. I am including a picture of the schema we created as well for this app. While I am not going into detail about how to create the tables and models in Rails that is not the purpose of this article. The purpose is to simply show what these AR Macros do and what they give us.
Now we are able to start diving into what these Macros actually give us. So for example say I needed to pull out the just the name of the artist who created a specific song. The macros established in the Songs table are belongs_to : artist and also belongs_to:instrument. In order for this song to exist it needs both of the unique IDs that are generated when with the Artist or the Instrument were made. In the joiner models we call the unique identifiers “foreign keys”. The foreign keys tie a specific instance of the Artist model and a specific instance of Instrument to the Song name itself. This is what gives us access to the instance methods we established when we created the Artist and the Instrument. So back to what we are trying to do which is retrieve the name of the Artist tied to a specific song. In the rails console we are able to test out to see if our relationships are working properly. I am going to type into my console [Song.first.artist] and this is what we get.
Wait a min…. “You said we wanted the name but this isn’t displaying the name….”. Yes I am aware and i did that intentionally to show what is actually being retrieved written that way. Ask yourself what is it that was returned? Was it the name? The age? Their title? The answer is yes all of that. Typing in the console the way we did retrieved the Artist instance that is associated with that Song! A light bulb might be blinking now in your head as to where I am going with this. Since we iterated over the Song class and retrieved the first instance and called on the artist we only returned the instance. Remember when we created the Artist (well I did you didn’t) the attributes we assigned became instance methods. So if we change what we type in the console now to [Song.first.artist.name] what do you think we will get back?
The king lives! We were successfully able to pull out the name of the artist who sang the Song. This all works because of what the macros are doing! In the joiner model we are able to call on the instance methods generated by the macros and the relationship they have. Obviously this is a much more in depth topic than the surface material that we covered but you should be able to at least say what a macro is and what is the purpose of it is. I hope this guide helps an aspiring programmer just a little bit as I am still just in the first steps of my journey and tried to put into my own words what Macros are doing. Please be kind with comments and enjoy your day! Happy Coding!