ActiveRecord Associations intro into 'has_many' 
Tags: beginners, ruby, backend, activerecord
Published: 2021-08-27 14:59:10

When learning about ActiveRecord in our coding bootcamp, they talked about the major benefits that ActiveRecord provides when working in Ruby and SQL. So I wanted to delve more into what is happening behind the scenes, and I discovered there is a *lot* that ActiveRecord is doing back there. So let's talk about one that we all use: `has_many`. 

`Has_many` is one of the 6 types of associations (or "macro methods") that ActiveRecord offers. 
A `has_many` association is similar to `has_one`, but indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a `belongs_to` association. This association indicates that each instance of the model has zero or more instances of another model. With the `has_many` association you will always want to make sure that whatever the model `has_many` of, is plural. For example, in an application containing a child and their toys, the child model could be declared like this:

```
class Child < ApplicationRecord
  has_many :toys
end
```
A `has_many :through` association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model. Also with the `has_many :through` association, you will still want to make sure that whatever the model `has_many` of is plural. For example, consider a game has reviews and users that can write reviews. The relevant many-to-many association declarations could look like this:

```
class Game < ApplicationRecord
  has_many :reviews
  has_many :users, through: :reviews
end

class Review < ApplicationRecord
  belongs_to :game
  belongs_to :user
end

class User < ApplicationRecord
  has_many :reviews
  has_many :games, through: :reviews
end
```
Okay, now that we have that basic setup of what the `has_many` table association can look like, lets get into what is auto-generated for you. Look at the list below:

```
others                            
others=(other,other,...)          
other_ids                         
other_ids=(id,id,...)             
others<<                          
others.push                       
others.concat                     
others.build(attributes={})       
others.create(attributes={})      
others.create!(attributes={})     
others.size                       
others.length                     
others.count                      
others.sum(*args)                 
others.empty?                     
others.clear                      
others.delete(other,other,...)    
others.delete_all                 
others.destroy(other,other,...)   
others.destroy_all                
others.find(*args)                
others.exists?                    
others.distinct                   
others.reset                      
others.reload     
```
These auto-generated methods can and will save us a ton of time when querying any database. 

Here is another cool thing that `has_many` can do: since associations are built from [Relation](https://api.rubyonrails.org/v6.1.4/classes/ActiveRecord/Relation.html) objects, you can add conditions to the query, like so:
```
class Blog < ActiveRecord::Base
  has_many :published_posts, -> { where(published: true) }, class_name: 'Post'
end
```
You can also read up on more of the capabilities that 'Association Methods' have, [Here](https://api.rubyonrails.org/v6.1.4/classes/ActiveRecord/Associations/ClassMethods.html).

Furthermore, if you would like to learn more about the other five associations, here is a link with detailed documentation on those association types and their use cases [ActiveRecord](https://guides.rubyonrails.org/association_basics.html#the-has-many-association).

In conclusion, `has_many` is a very helpful method that saves us a lot of time. I personally have made many methods not knowing that `has_many` already provided said method. So it's a good thing to to be curious about whats happening or what the method is doing for you. post in the comments below about a time when a 'Macro' method saved you time.