Backend/RubyOnRails

[RubyOnRails Guides] Active Record Query Interface - 1ํŽธ

Seyun(Marco) 2021. 3. 9. 21:40
728x90

[RubyOnRails Guides] Active Record Query Interface - 1ํŽธ

๐Ÿ’ผ ์„œ๋ก 

  • RubyOnRails Guides Active Record Basics ๋ฅผ ์ฐธ๊ณ ํ•ด ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.
  • Ruby version์€ 2.6.3์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Ruby On Rails version์€ 5.2.1์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ˜ฎ Active Record?

[RubyOnRails Guides] Active Record Basics

๐Ÿ“– DB Model ์กฐํšŒ(SELECT)

  • ๊ธฐ๋ณธ์ ์ธ Model.find(options)์˜ ํŠน์ง•์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • ์ œ๊ณต๋œ ์˜ต์…˜์„ ๋™๋“ฑํ•œ SQL๋กœ ๋ณ€ํ™˜
    • SQL ์ฟผ๋ฆฌ๋ฅผ ์‹œ์ž‘ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ํ•ด๋‹น ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ƒ‰
    • ๋ชจ๋“  ๊ฒฐ๊ณผ ํ–‰์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ๋ชจ๋ธ์˜ Ruby Instanceํ™”
    • after_find๋ฅผ ์‹คํ–‰ํ•œ ํ›„ after_initialize ์ฝœ๋ฒก์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“– DB Model ๋‹จ๊ฑด ๋ฐ ์—ฌ๋Ÿฌ๊ฑด ์กฐํšŒ

find

  • ๊ธฐ๋ณธํ‚ค(PK) ๊ธฐ๋ฐ˜์˜ id ๊ฐ’์œผ๋กœ ์กฐํšŒํ•˜๋Š” ๋ฉ”์„œ๋“œ ์ž…๋‹ˆ๋‹ค.
User.find(1)

SELECT * FROM users WHERE (users.id = 1) LIMIT 1
  • ํ•ด๋‹น Model์„ ์กฐํšŒํ•˜์ง€ ๋ชปํ•  ๊ฒฝ์šฐ ActiveRecord::RecordNotFound ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
  • ๊ธฐ๋ณธํ‚ค ๋ฐฐ์—ด์„ ์ œ๊ณตํ•˜๋ฉด ์—ฌ๋Ÿฌ๊ฐœ์˜ Model์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
User.find([1, 10])

SELECT * FROM users WHERE (users.id IN (1, 10))

take

  • ์ˆœ์„œ์—†์ด ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
User.take

SELECT * FROM users LIMIT 1
  • ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๊ณ  ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด take ๋ฉ”์„œ๋“œ๋Š” ni(NULL)l์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฒฐ๊ณผ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
User.take(2)

SELECT * FROM users LIMIT 2

first

  • ๊ธฐ๋ณธํ‚ค๋กœ ์ •๋ ฌ๋œ ์ฒซ๋ฒˆ์งธ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
User.frist

SELECT * FROM users ORDER BY users.id ASC LIMIT 1
  • ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ์•„๋‹Œ nil(NULL)์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ Model์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
User.first(3)

SELECT * FROM clients ORDER BY users.id ASC LIMIT 3
  • order ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํ•„๋“œ๋กœ ์ •๋ ฌ ํ›„ ์ฒซ๋ฒˆ์จฐ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
User.order(:name).first

SELECT * FROM users ORDER BY users.name ASC LIMIT 1

last

  • ๊ธฐ๋ณธํ‚ค๋กœ ์ •๋ ฌ๋œ ๋งˆ์ง€๋ง‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
User.last

SELECT * FROM users ORDER BY users.id DESC LIMIT 1
  • ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ์•„๋‹Œ nil(NULL)์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ Model์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
User.last(3)

SELECT * FROM clients ORDER BY users.id DESC LIMIT 3
  • order ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํ•„๋“œ๋กœ ์ •๋ ฌ ํ›„ ๋งˆ์ง€๋ง‰ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
User.order(:name).last

SELECT * FROM users ORDER BY users.name DESC LIMIT 1

find_by

  • ์ผ๋ถ€ ์กฐ๊ฑด๊ณผ ์ผ์น˜ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
User.find_by first_name: 'rutgo'
User.where(first_name: 'rutgo').take

SELECT * FROM users WHERE (users.first_name = 'rutgo') LIMIT 1
  • ์ผ์น˜ํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ์—๋Š” ActiveRecord:RecordNotFound ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ

all

  • ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฉ”์†Œ๋“œ๋กœ ๋งŽ์€ ์ˆ˜์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์ „์ฒด ์ปฌ๋ ‰์…˜์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ์–‘์„ ์ดˆ๊ณผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Rails๋Š” ๋ฐฐ์น˜๋กœ ๋ถ„ํ• ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š”๋ฐ ์•„๋ž˜์—์„œ ์‚ดํŽด๋ณผ find_each ์™€ :batch_size ์ž…๋‹ˆ๋‹ค.

find_each

  • Model์ด ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ํƒ์ƒ‰ ํ›„์— ๊ฐ ๋ ˆ์ฝ”๋“œ์˜ ๊ฐ์ฒด ๋ฐ์ดํ„ฐ ๋ธ”๋ก ๋‚ด์— ๊ฐœ๋ณ„์ ์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ผ๊ด„์  ํƒ์ƒ‰ ํ›„ record๋ฅผ block์— ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
User.find_each do |user|
     NewsMailer.weekly(user).deliver_now
end
  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์ด์ฆˆ๋Š” 1000์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ต์…˜์„ ํ†ตํ•ด ์„ค์ •ํ• ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  • :batch_size
    • Record ์ˆ˜ ์กฐ์ ˆ
  • :start
    • ๋ฐ์ดํ„ฐ ํƒ์ƒ‰ ์‹œ์ 
  • :finish
    • ๋ฐ์ดํ„ฐ ํƒ์ƒ‰ ์ข…๋ฃŒ ์ง€์ 
  • :error_on_ignore
    • ๊ด€๊ณ„์— order๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์žฌ๊ตฌ์„ฑ ํ•ฉ๋‹ˆ๋‹ค.

find_in_batches

  • ๊ฐœ๋ณ„์ ์ด ์•„๋‹ˆ๋ผ collection ํ˜•ํƒœ๋กœ Model์˜ ๋ฐฐ์—ด๋กœ block์— Batch๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
Invoice.find_in_fatch do |invoices|
    export.add_invoices(invoices)
end
  • ์˜ต์…˜์€ find_each ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๐Ÿ•น ์กฐ๊ฑด

where

  • SQL WHERE์ ˆ๊ณผ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
Client.where("orders_count = '2'")

SELECT * FROM clients WHERE clients.orders_count = 2
  • ์ฃผ์˜ํ•ด์•ผํ•  ์ ์€ SQL Injection ๊ณต๊ฒฉ์— ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์ด prepared Statement์˜ parameterized query ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

  • ๋ฐฐ์—ด๋„ ์กฐ๊ฑด์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ๋ฐฐ์—ด ใ…‡๋‹ˆ์ž๋กœ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Client.where("orders_count = ?", params[:orders])
Client.where("orders_count = ? AND locked = ?", params[:orders], false)
  • ๋˜ํ•œ key/value hash์™€ ํ•จ๊ป˜ ํ‚ค๋ฅผ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
Client.where("created_at >= :start_date AND created_at <= :end_date", {start_date: params[:start_date], end_date: params[:end_date]})
  • ๊ฐ€๋…์„ฑ์„ ๋†’์ด๋„๋ก Hash Condtion๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
Client.where(locked: true)

SELECT * FROM clients WHERE (clients.locked = 1)

Client.where('locked' => true)
  • ์ถ”๊ฐ€์ ์œผ๋กœ belons_to ๊ด€๊ณ„์ผ ๊ฒฝ์šฐ ์—ฐ๊ด€ํ‚ค๋ฅผ ์ด์šฉํ•ด join๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
Article.where(author: author)
Author.joins(:articles).where(articles: { author: author })
  • ๋ฒ”์œ„ ์กฐ๊ฑด์ธ BETWEEN ~ AND ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
Client.where(created_at: (Time.mow.midnight - 1.day)..Time.now.midnight)

SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')
  • ๋˜ํ•œ IN ํ‘œํ˜„์‹๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
Client.where(orders_count: [1,3,5])

SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
  • NOT ํ‘œํ˜„์‹๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
Client.where.not(locked: true)

SELECT * FROM clients WHERE (clients.locked != 1)
  • OR ํ‘œํ˜„์‹๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
Client.where(locked: true).or(Client.where(orders_count: [1,3,5]))

SELECT * FROM clients WHERE (clients.locked = 1 OR clients.orders_count IN (1,3,5))

order

  • ์ •๋ ฌ์„ ํ•ด์ฃผ๋Š” order ํ‘œํ˜„์‹์— ๋Œ€ํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค.
  • default๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ์ด ๋ฉ๋‹ˆ๋‹ค.
Client.order(:created_at) # ์˜ค๋ฆ„์ฐจ์ˆœ
Client.order(created_at: :desc) # ์˜ค๋ฆ„์ฐจ์ˆœ ๋ช…์‹œ
Client.order(created_at: :asc) # ๋‚ด๋ฆผ์ฐจ์ˆœ
Client.order(orders:count: :asc, created_at :desc) #์—ฌ๋Ÿฌ ํ•„๋“œ๋„ ์ •๋ ฌ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
Client.order("orders_count ASC").order("created_at DESC") # ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœ ๋˜์–ด๋„ ํ•˜๋‚˜์˜ ORDER BY๋ฌธ์œผ๋กœ ๋ฌถ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

SELECT * FROM clients ORDER BY orders_count ASC, created_at DESC

๐ŸŽ– ํŠน์ • ํ•„๋“œ๋งŒ ์„ ํƒ

  • find ๋ฉ”์†Œ๋“œ๋Š” SELECT *๊ณผ ๊ฐ™์ด ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ • ํ•„๋“œ๋งŒ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” select ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
Client.select("viewable_by, locked")

SELECT viewable_by, locked FROM clients

Client.seelect(:name).distinct # ์ค‘๋ณต ์ œ๊ฑฐ

SELECT DISTINCT name FROM clients
  • ๊ณ ์œ ์„ฑ ์ œํ•œ ์กฐ๊ฑด์„ ์ œ๊ฑฐํ• ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
query = Client.select(:name).distinct

query.distinct(false)

โ›”๏ธ Limit & Offset

Clinet.limit(5).offset

SELECT * FROM clients LIMIT 5 OFFSET 30

๐ŸŽณ Group

Order.select("date(created_at as ordered_date, sum(price) as total_price").group("date(created_at)")

SELECT date(created_at) as ordered_date, sum(price) as total_price
FROM orders
GOUP BY date(created_at)
  • ๋‹จ์ผ ์ฟผ๋ฆฌ๋กœ ๊ทธ๋ฃนํ™” ๋œ ์ด ๊ฐฏ์ˆ˜๋„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Order.group(:status).count

SELECT COUNT (*) AS count_all, status AS status
FROM "orders"
GROUP BY status

Having

  • HAVING ์ ˆ๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created)at)").having("sum(price) > ?", 100)

SELECT COUNT (*) AS count_all, status AS status
FROM "orders"
GROUP BY status

๐Ÿšซ Condition Ignore(์กฐ๊ฑด ๋ฌด์‹œ)

unscope

  • ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋ฉ”์†Œ๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊ฐ™์€ ๊ฒฝ์šฐ์— ORDER BY๊ฐ€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๊ฑธ ๋ณผ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Article.where('id > 10').limit(20).order('id asc').unscope(:order)

SELECT * FROM articles WHERE id > 10 LIMIT 20
  • ํŠน์ • WHERE์ ˆ์˜ ๋ฒ”์œ„๋ฅผ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Article.where(id: 10, trashed: false).unscope(where: :id)

SELECT "articles".* FROM "articles" WHERE trashed = 0
  • unscope๋ฅผ ์‚ฌ์šฉํ•œ ๊ด€๊ณ„(relation)๋Š” merge ๊ด€๊ณ„์— ์žˆ์–ด๋„ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
Article.order('id asc').merge(Article.unscope(:order))

SELECT "articles".* FROM "articles"

only

  • ์กฐ๊ฑด์„ ์žฌ์ •์˜ํ•  ์ˆ˜ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
Article.where('id > 10').limit(20).order('id desc').only(:order, :where)

SELECT * FROM articles WHERE id > 10 ORDER BY id DESC

#only ์—†๋Š” query
SELECT * FROM articles WHERE id > 10 ORDER BY id DESC LIMIT 20

reselect

Post.select(:title, :body).reselect(:created_at)

SELECT 'posts'.'created_at' FROM 'posts'

# reselect๊ฐ€ ์—†๋Š” ์ฟผ๋ฆฌ
SELECT `posts`.`title`, `posts`.`body`, `posts`.`created_at` FROM `posts`

reorder

  • ์ˆœ์„œ๋ฅผ ์žฌ์ •์˜ ํ•ฉ๋‹ˆ๋‹ค.
class Article < ApplicationRecord
  has_many :comments, -> { order('posted_at DESC') }
end

Article.find(10).comments.reorder('name')

SELECT * FROM articles WHERE id = 10 LIMIT 1
SELECT * FROM comments WHERE article_id = 10 ORDER BY name

# reorder๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
SELECT * FROM articles WHERE id = 10 LIMIT 1
SELECT * FROM comments WHERE article_id = 10 ORDER BY posted_at DESC

reverse_order

  • ์ง€์ •๋œ ์ˆœ์„œ๋ฅผ ๋ฐ˜๋Œ€๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
Client.where("orders_count > 10").order(:name).reverse_order

SELECT * FROM clients WHERE orders_count > 10 ORDER BY name DESC
  • order๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธํ‚ค ๊ธฐ์ค€์œผ๋กœ reverse ๋ฉ๋‹ˆ๋‹ค.

rewhere

  • where ์กฐ๊ฑด์„ ์žฌ์ •์˜ ํ•ฉ๋‹ˆ๋‹ค.
Article.where(trashed: true).rewhere(trashed: false)

SELECT * FROM articles WHERE `trashed` = 0
  • rewhere์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
Article.where(trashed: true).where(trashed: false)

SELECT * FROM articles WHERE `trashed` = 1 AND 'trashed' = 0

๐Ÿ“ญ Null

  • none ๋ฉ”์„œ๋“œ๋Š” ๋ ˆ์ฝ”๋“œ๊ฐ€ ์—†๋Š” ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•œ ๊ด€๊ณ„๋ฅดใ…ใ„น ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ˜ํ™˜๋œ ๊ด€๊ณ„์— ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ํ›„์† ์กฐ๊ฑด์€ ๊ณ„์† ๋นˆ ๊ด€๊ณ„๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
Article.none

๐Ÿ˜ฎ readOnly

  • ์ฝ๊ธฐ ์ „์šฉ Model๋กœ ์ˆ˜์ •์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค.
  • ๋ณ€๊ฒฝํ•˜๋ฉด ActiveRecord::ReadOnlyRecord ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
Client.readonly.first
client.visits += 1
client.save # ์˜ˆ์™ธ ๋ฐœ์ƒ

๐Ÿ˜‡ ๊ฒฐ๋ก 

  • Rails๋Š” Active Record๋กœ ORM ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • Query Interface๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ Query๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ DB SQL์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋Œ€๋ถ€๋ถ„์˜ Query ๋ช…๋ น๋ฌธ์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๊ฐ€ Query์— ์ง‘์ค‘ํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ vender์— ๋งž์ถฐ SQL์ด ์กฐ๊ธˆ์”ฉ ๋‹ค๋ฅธ๋ฐ ์† ์‰ฝ๊ฒŒ vender๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ๋„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • 2ํŽธ์—์„œ๋Š” Lock, Join, Eger Loading ๋“ฑ์„ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜

Active Record Query Interface - Ruby on Rails Guides

728x90
728x90