[Rails] Model Association (Association)

A memorandum of the (association) type of Rails model References: Rails Guide https://railsguides.jp/association_basics.html

Reasons for associating

The connection between two Active Record models is called an association. Below, the association will be described in a unified manner with the association. The reason for associating ・ Allows common operations between models, making code writing simple and easy ・ The above will improve the visibility of the code. Because.

Example Taking a simple task management application as an example, we will write the association between the user (User) and the task (Task). (Write according to the Rails guide)

class User < ApplicationRecord
end

class Task < ApplicationRecord
end

If the user describes the case of adding a new task and the case of deleting the user without association, the implementation will be as follows.

#Add new task
@task = Task.create(task: "shopping", user_id: @user.id)

#Delete user(In this case, if you do not delete all the tasks of the user to be deleted together, meaningless data will be left in the DB forever.)
@tasks = Task.where(user_id: @user.id)
@tasks.each do |task|
  task.destroy
end
@user.destroy

By explicitly adding associations to your Rails model, you can write your code more concisely. First, define the model association.

class User < ApplicationRecord
 #The user has multiple tasks,Defined that when a user is deleted, delete all tasks as well
  has_many :tasks, dependent: :destroy
end

class Task < ApplicationRecord
 #Tasks are created by one user
  belong_to :user
end

This completes the association. If you explain has_many and belong_to quite roughly

From the user's point of view, it can have multiple tasks such as Task_a, Task_b, Task_c, Seen from Task, there is only one User I defined it in Rails as a one (User) to many (Task) relationship.

By the way, the dependent :: destroy option is When a user is deleted, it means that all tasks of that user should be deleted.

By making the association as above, Adding new tasks and deleting users can now be described briefly as follows.

#Add new task
@task = @user.tasks.create(task: "shopping")

#Delete user(dependent: :The destroy option also deletes the user's task.)
@user.destroy

In particular, the deleted part requires only one line for five lines. Looking at the code, I could immediately understand what I was doing and the outlook improved.

Association type

belongs_to has_one has_many has_many :through has_one :through has_and_belongs_to_many

Description

belong_to A one-to-one association is set. All instances of the declaring model "belongs to" an instance of the other model. Taking the example chapter as an example, it expresses the relationship of assigning one user to one task. The model name specified in the belongs_to association must always be "singular".

 #Since there is only one user, it must be singular.
 #Rails automatic guess results in an error.
class Task < ApplicationRecord
  belong_to :user
end

has_one A one-to-one association is set. The difference from belong_to is Indicates that the instance of the model in which the declaration is made "contains" or "owns" an instance of the other model. Take the National Health Insurance card as an example (difficult to understand (laughs)?)

One person owns one insurance card.
class people < ApplicationRecord
  has_one :insurance_card
end

One person has a health insurance card.
class insurance_card < ApplicationRecord
  belong_to :people
end

has_many Indicates that there is a "one-to-many" connection. If the has_many association is used, an instance of that model owns "zero or more" instances of the opposite model. Taking the example chapter as an example, it is possible to express a relationship in which one user has multiple tasks. When declaring a has_many association, the model name of the other party must be "plural".

 #Since multiple tasks can be owned by one user, they must be described in the plural form.
 #Rails automatic guess results in an error.
class User < ApplicationRecord
  has_many :tasks
end

has_many :through Often used to set up a "many-to-many" connection. This association creates a "third model (intermediate model)" between the two models. As a result, it matches with "0 or more" instances of the opponent model. It is possible to limit the students who attend a specific lesson from multiple lessons and multiple students.

Students are taking multiple lessons.
class Student < ApplicationRecord
  has_many :members
  has_many :class_works, through: :members
end

By saving the ids of multiple lessons and multiple students, it is possible to limit the students who are in a specific lesson.
class Member < ApplicationRecord
  belongs_to :student
  belongs_to :class_work
end

Classes are taken by multiple students.
class Class_work < ApplicationRecord
  has_many :members
  has_many :students, through: :members
end

has_one :through Set a "one-to-one" connection. This association creates a "third model (intermediate model)" between the two models. It matches one instance of the other model. I can't think of it, so I'll take the Rails guide as an example.

If one provider is associated with one account, and one account is associated with one account history, the supplier model looks like this:

#Supplier has an account and accout through the account_Have history.
class Supplier < ApplicationRecord
  has_one :account
  has_one :account_history, through: :account
end

#account belongs to supplier and account_Have one history
class Account < ApplicationRecord
  belongs_to :supplier
  has_one :account_history
end

#Account History belongs to accout
class AccountHistory < ApplicationRecord
  belongs_to :account
end

has_and_belongs_to_many Create a "many-to-many" connection. However, unlike the case where through: is specified, there is no third model (intermediate model). If there is an assembly and a part, and many parts correspond to one finished vehicle, and conversely many completed vehicles correspond to one part, the model declaration is as follows. Will be.

#The finished car has many parts(parts)Is attached and becomes a car.
class Assembly < ApplicationRecord
  has_and_belongs_to_many :parts
end

#There are multiple parts, which are attached to multiple finished vehicles.
class Part < ApplicationRecord
  has_and_belongs_to_many :assemblies
end

Recommended Posts

[Rails] Model Association (Association)
Model association in Rails
Ruby On Rails Association
rails g model Overall flow
About naming Rails model methods
[Rails] Japaneseize model attribute names
Rails model and table naming conventions
[Rails g.error]
Association (many-to-many)! !!
Rails basics
Rails Review 1
Rails API
Rails migration
[Rails] Unit test code for User model
[Rails] first_or_initialize
rails tutorial
[Ruby on Rails] 1 model CRUD (Routing Main)
Association (one-to-many)! !!
About Rails 6
[Ruby on Rails] model, controller terminal command
Ruby on Rails model creation / deletion command
Rails foundation
Rails memorandum
rails tutorial
rails tutorial
MVC model
Rails association gives one-to-many relationships between models
Association (1 to 1)! !!
[Rails] devise
[Ruby on Rails] Model test with RSpec
rails tutorial
rails tutorial
Rails Tips
rails method
rails tutorial
[Rails] ActiveRecord
[Rails] form_with
Rails Review 2
Get child model with rails created_at desc scope
Create an EC site with Rails5 ⑤ ~ Customer model ~
belongs_to association foreign_key option (Rails Guide personal translation)