728x90
[RubyOnRails Guides] Active Record Basics
๐ผ ์๋ก
- RubyOnRails Guides Active Record Basics ๋ฅผ ์ฐธ๊ณ ํด ์์ฑํ ๊ธ์ ๋๋ค.
- Ruby version์ 2.6.3์ ์ฌ์ฉํฉ๋๋ค.
- Ruby On Rails version์ 5.2.1์ ์ฌ์ฉํฉ๋๋ค.
๐ฎ Active Record?
- MVC ํจํด ์ค M์ ํด๋น ๋๋ฉฐ Rails์์ ์ ๊ณตํ๋ ๋ชจ๋๋ก ์ฃผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ก์ง์ ์ ์ดํ๋๋ฐ ์์ด ์ฌ์ฉ๋ฉ๋๋ค.
- Active Record๋ ORM(Object Relational Mapping) ๋ฌธ๋ฒ์ ํตํด DB๋ฅผ ์ ์ดํ๊ฒ ๋ฉ๋๋ค.
ORM(Object Relational Mapping)
- ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ๊ณผ Model(Object)๋ฅผ ๋งคํํ๋ ๊ธฐ์ ๋ก SQL๋ฌธ์ ์ง์ ์์ฑํ์ง ์๊ณ ๋ DB๋ฅผ ์ก์ธ์ค ํ ์ ์์ผ๋ฉฐ, ๋ชจ๋ธ์ ์์ฑ ๋ฐ ๊ด๊ณ๋ฅผ DB์ ์ฝ๊ฒ ์ ์ฅํ๊ณ ์กฐํํ ์ ์์ต๋๋ค.
ORM์ Active Record ํน์ง
- ๋ชจ๋ธ๊ณผ ๋ฐ์ดํฐ๋ฅผ ๋ํ๋ธ๋ค.
- ๋ชจ๋ธ ๊ฐ์ ์ฐ๊ด์ฑ์ ๋ํ๋ธ๋ค
- ์์ ๊ณ์ธต์ ๋ํ๋ธ๋ค
- ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ ๊ณตํ๋ค.
- ๊ฐ์ฒด ์งํฅ์ ์ผ๋ก DB ์์ ์ ์ํํ๋ค.
๐ฎโโ๏ธ Active Record Configuration์ ๊ท์น
Naming Convention
- ๋ชจ๋ธ์ ๋จ์๋ก DB ํ
์ด๋ธ์ ๋ณต์๋ก ์์ฑํฉ๋๋ค. ๋ํ ๋ชจ๋ธ์ ์ฒซ ๊ธ์๋ฅผ ๋๋ฌธ์๋ก ์ฌ์ฉํ๋ UpperCamelCase๋ฅผ ์ฌ์ฉํ๋ฉฐ DB์ ํ
์ด๋ธ์ ๋ชจ๋ ์๋ฌธ์๋ก ์ฌ์ฉํ๋ฉด์ ๊ฐ ๋จ์ด์ ์ฌ์ด๋ฅผ ์ธ๋๋ฐ(_)๋ก ํ๋ snake_cate๋ฅผ ์ฌ์ฉํ๋ค.
- ex) Article / articles
- ex) LineItem / line_items
Schema Convention
Foreign keys(์ธ๋ํค)๋ [singularized_table_name]_id๋ก ์๋์ ์์์ ๊ฐ์ด ์์ฑํฉ๋๋ค.
- order_id
- article_id
Primary Keys
- ๊ธฐ๋ณธํค๋
id
๋ผ๋ ์ด๋ฆ์ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
- ๊ธฐ๋ณธํค๋
created_at
- ์์ฑ ๋ ์ง
updated_at
- ์์ ๋ ์ง
lock_version
- ๋๊ด์ ์ ๊ธ
type
- ๋จ์ผ ํ ์ด๋ธ ์์
(association_name)_type
- ๋คํ์ฑ ๊ฐ์ฒด ์ด๋ฆ
(table_name)_count
- ์ฐ๊ด๊ด๊ณ(has_many)์ ์ํ ๊ฐ์ฒด์ ์๋ฅผ ์บ์ํ๋๋ฐ ์ฌ์ฉ
Tip
- created_at, updated_at์ Migration ํ์ผ ์์ :t.timestemp์ ์ํด ์๋์ผ๋ก ์์ฑ๋๊ฒ ๋ฉ๋๋ค.
๐จโ๐จ Active Record Models ์์ฑ
- ApplicationRecord ์์ํ๋ ์๊ฐ Active Record๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
class Product < ApplicationRecord
end
Naming Convetion ์ฌ์ ์
self.table_name
๋ก ํ ์ด๋ธ ์ด๋ฆ์ ์ง์ ํ ์ ์์ต๋๋ค.
class Product < ApplicationRecord
self.table_name = "my_products"
end
- text class๋ ๋ณ๊ฒฝํด์ค์ผ ํฉ๋๋ค.
class ProductTest < ActiveSupport::TestCase
set_fixture_class my_products: Product
fixtures :my_products
...
end
- ๊ธฐ๋ณธ ํค๋ ์ฌ์ ์ ํ ์ ์์ต๋๋ค.
class Product < ApplicationRecord
self.primary_key = "product_id"
end
๐ฆ CRUD - Create
๋ชจ๋ธ๋ช .create()
๋ฅผ ์ด์ฉํด ๋ชจ๋ธ์ ์์ฑํ ์ ์์ต๋๋ค.
user User.create(name: "David", occupation: "Code Artist")
- new() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํ ํ ์ ์์ต๋๋ค.
user = User.new
user.name = "David"
user.occupation = "Code Artist"
user.save
- save ํจ์๋ฅผ ์ด์ฉํด ์ ์ฅํ ์ ์์ต๋๋ค.
๐ CRUD - Read
User.all # ๋ชจ๋ User Model์ ๊ฐ์ ธ์ค๋ ํจ์
User.first # ์ฒซ๋ฒ์งธ User Model์ ๊ฐ์ ธ์ค๋ ํจ์
User.find_by(name: 'rutgo') #name์ ์ด์ฉํด ์กฐํํ๋ ํจ์
User.where(name: 'rutgo', age: 29).order(created_at: :desc) # SELECT ์ฟผ๋ฆฌ์ WHERE ์ ์ ์ถ๊ฐํ๊ณ created_at์ ์ด์ฉํด ์ ๋ ฌํ๋ ํจ์
๐ CRUD - Update
@user = User.find_by(name: 'rutgo');
user.name = 'marco'
user.save
- ์์ ๊ฐ์ด ์ด๋ฆ์ ํ๋๊ฐ๋ง ๋ณ๊ฒฝํ๊ณ ๋ค์ save๋ฅผ ํ๋ฉด ์์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
- ์์ ์ฝ๋๋ฅผ update ํจ์๋ก ์ข ๋ ์ค์ผ ์๋ ์์ต๋๋ค.
user = User.find_by(name: 'rutgo')
user.update(name: 'marco')
- ์ฌ๋ฌ๊ฐ๋ฅผ update์ ํ ๊ฒฝ์ฐ update_all ๋ฉ์๋๊ฐ ์ ์ฉํฉ๋๋ค.
User.update_all "max_login_attempts = 3, must_change_password = 'true'"
โฐ๏ธ CRUD - Delete
user = User.find_by(name: 'rutgo')
user.destroy
- ์ฌ๋ฌ๊ฐ๋ฅผ ์ญ์ ํ ๊ฒฝ์ฐ destroy_all ๋ฉ์๋๊ฐ ์ ์ฉํฉ๋๋ค.
User.where(name: 'rutgo').destroy_all # ํน์ ์กฐ๊ฑด์ ๋ง๋ User Model ์ญ์
User.destroy_all # ๋ชจ๋ User Model ์ญ์
๐จโโ๏ธ Validation
- DB์ ์ ์ฅ๋๊ธฐ ์ ์ Model์ ์ํ๋ฅผ ํ์ธํด ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํ ์ ์์ต๋๋ค.
class User < ApplicationRecord
validates :name, presence: true
end
- ์์ ๊ฐ์ด validates๋ก validationํ ํ๋์ presence๋ ๋น๊ฐ์ ํ์ฉํ์ง ์๋๋ค๊ณ ์๊ฐํ๋ฉด ์ข์ค๋น๋ค.
- ๋ฐ๋ผ์ ์๋์ ๊ฐ์ด ์คํํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
user = User.new
user.save # return false
user.save! # Exception
- save, update ๋ฉ์๋๋ฅผ ์คํํ ๋ validate๋ ์คํ๋๋ฉฐ ์คํจ ์ฑ๊ณต์ true/false๋ก ๊ตฌ๋ถํฉ๋๋ค. ์ข ๋ ์๊ฒฉํ๊ฒ Exception์ ๋ฐ์์ํค๊ณ ์ถ๋ค๋ฉด save!, update! ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
- ์์ธํ ๋ด์ฉ์ Active Record Validations ๋ฅผ ์ฐธ๊ณ ํ์ธ์.
โ๏ธ Callback
- Model ๋ด์์ ์ด๋ฒคํธ๊ฐ ์ฒ๋ฆฌ ๋๊ธฐ ์ ์ ๋ด๋ถ์ ์ผ๋ก ์ด๋ค ์ด๋ฒคํธ ๋ฐ์ ์ ๋๋ ํ์ ๊ฒ์ฆํ๋ ๋จ๊ณ์ ๋๋ค.
- ์ฆ, SQL ํธ๋์ญ์ ์๋ ์ (before) ๋ฐ ํ(after)์ ์์ ๋กญ๊ฒ ์ ๊ทผ์ด ๊ฐ๋ฅํฉ๋๋ค.
- ์์ธํ ๋ด์ฉ์ Active Record Callback ์ ์ฐธ๊ณ ํ์ธ์.
๐ Migrations
- Migration์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผ ๋ฐ ์คํค๋ง๋ฅผ ๊ด๋ฆฌํ๋ ํ์ผ์ ๋๋ค.
- rails g model ~ ์ ์คํํ๋ฉด model๊ณผ Migration ํ์ผ์ด ์์ฑ๋๋ ๊ฑธ ์ ์ ์์ต๋๋ค. Migration์ Table์ ๋ช ์ธ์๋ผ๊ณ ์๊ฐํ๋ฉด ์ข์ต๋๋ค. ๋ฐ๋ผ์ Table๋ค์ Column๋ค์ ๊ท์น ๋ฑ์ ์ ์ํด๋์ต๋๋ค.
- Migration์ ํ๊ธฐ ์ํด์๋
rake db:migration
/rails db:migration
๋ช ๋ น์ด๋ฅผ ์คํํ๋ฉด ๋ฉ๋๋ค. - ์ค๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ฅผ ์ํด Rollback ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
rake db:rollback
- ๋ํ Migration์ DB(PostgreSQL, MySQL, Orcle) ๋ฑ์์ ๋ชจ๋ ์ ์ฉ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ํธํ์ฑ์ ๊ฑฑ์ ํ ํ์๊ฐ ์์ต๋๋ค.
- ์์ธํ ๋ด์ฉ์ Active Record Migrations ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.
๐ ๊ฒฐ๋ก
- Rails๋ Active Record๋ก ORM ๊ธฐ๋ฅ์ ์ง์ํฉ๋๋ค.
- ์ฝ๊ฒ DB๊ด๋ จ ๋ก์ง๋ค์ ์์ฑํ ์ ์์ผ๋ฉฐ, ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ ๋ฉ์๋๋ค๋ก ๊ฐ๋ฐ์๋ค์ ์ฟผ๋ฆฌ ์์ฐ์ ์ต์ํ๋ฅผ ํด์ค๋๋ค.
- ๋ํ ์ ํํ ๋ช ๋ช ๊ท์น์ ๋ช ์ํด๋์์ผ๋ก์จ ๊ฐ๋ฐ์๋ค๊ฐ์ ์ํต์ ์ข ๋ ์ ์ฉํ๊ฒ ํด์ฃผ๋๊ฒ ๊ฐ๊ธฐ๋ ํฉ๋๋ค.
- ๋ฉ์๋ ์ฒด์ด๋์ ํตํด Query Method๊ฐ ๊ฐ๋ฅํจ์ผ๋ก์จ ์ข ๋ ๊ฐ๋ ์ฑ์ด ๋์์ง๋๊ฒ ๊ฐ์ต๋๋ค.
- ๋ํ Migaration ๊ธฐ๋ฅ์ ํตํด Model๊ณผ DB Table์ ๊ฐ๊ทน์ ๋ง์ด ํด๊ฒฐํด์ฃผ๋ฉฐ, ๊ฐ๋ฐ์๋ Model์ ๋ํ ์ง์์ ํตํด ๊ฐ๋ฐํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋๊ฒ ๊ฐ์ต๋๋ค ๐
์ถ์ฒ
728x90
728x90
'Backend > RubyOnRails' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[RubyOnRails Guides] Active Record Query Interface - 2ํธ (0) | 2021.03.09 |
---|---|
[RubyOnRails Guides] Active Record Query Interface - 1ํธ (0) | 2021.03.09 |
RubyOnRails Getting Start(Blog ๋ง๋ค๊ธฐ) 4ํธ(๋ง์ง๋ง๐จโ๐จ) (0) | 2021.02.16 |
RubyOnRails Getting Start(Blog ๋ง๋ค๊ธฐ) 3ํธ (0) | 2021.02.16 |
RubyOnRails Getting Start(Blog ๋ง๋ค๊ธฐ) 2ํธ (0) | 2021.02.16 |