- symbol과 string의 차이는 무엇인가요?
- symbol은 한번 정해진 값에 대해선 바꿀 수 없으나, (그렇다고, symbol로 초기화된 변수를 아예 건들지 못하는건 아님, :other_symbol과 같이다른 symbol 혹은 type으로 덮어쓰기가 가능) string은 중간에 내용을 바꿀 수 있다는 차이점이 있음.
a = :something_symbol
=> :something_symbol
a += "hello, world"
NoMethodError: undefined method `+' for :something_symbol:Symbol
a = :other_symbol
=> :other_symbol
a = "great job"
=> "great job"
b = "hello"
b += " world"
=> "hello world"
- 같은 이름의 symbol에 대해선 메모리를 서로 공유하다 보니 string에 비해 접근성이 빠름.
## symbol
:good.object_id
=> 1208988
:good.object_id
=> 1208988
## string
"hello".object_id
=> 70178679894640
"hello".object_id
=> 70178667293320
- self 는 무엇인가요?
class 내에 클래스 메소드
로서 쓰이는 개념,
사전에 something = Cal.new
와 같이 객체를 생성하지 않아줘도 됨.
class Cal
def self.plus(a, b)
return a+b
end
end
Cal.plus(3, 5)
=> 8
- 생성자(constructor)을 사용하는 방법은 무엇인가요?
initialize
메소드를 정의해주면 됩니다.
class Cal
def initialize
@init_number = 32
end
def plus(b)
return @init_number+b
end
end
data = Cal.new
data.plus(2)
=> 34
- Ruby가 dynamic programming language 임을 나타내는 특징들은 무엇인가요.
프로그램이 실행중에 다른프로그래밍 코드를 읽고, 생성하고, 변경할 수 있게 하며 심지어는 자신의 구조도 스스로 수정이 가능하게 하는 프로그래밍 방법입니다. 루비의 동적 프로그래밍 특성을 위 설명 그대로 확인할 수 있는 대표적인 예시는 eval 메소드로, string을 코드로 인식시키는 메소드 입니다.
# 아무 함수도 없는 EvalClass를 정의 한다.
class EvalClass
end
instance = EvalClass.new
# hello 라는 함수가 없는 것을 확인 한다.
instance.hello # undefined method 'hello' for #<EvalClass ....>
# 실행중 class_eval 을 이용해서 없던 함수를 추가한다.
EvalClass.class_eval do
def hello
puts 'class_eval bind method'
end
end
instance.hello # => class_eval bind method
# 실행중 class_eval 을 이용해서 방금 추가했던 함수를 같은이름의 새로운함수로 교체한다!'
EvalClass.class_eval do
def hello
puts 'class_eval modify method'
end
end
instance.hello # => class_eval modify method
- 동적인 함수명을 실행(invoke) 하는 방법을 설명하세요.
send
메소드를 활용하면 됩니다.
class Cal
def self.plus(a, b)
puts "a+b = #{a+b}"
return a+b
end
Cal.send(:plus, 2, 3)
end
||=
의 역할은 무엇인가요?
변수가 nil
혹은 false
일 경우 ||= 이 가리키는 value로 다시 초기화 합니다.
## nil 케이스
@flower = nil
@flower ||= "rose"
=> "rose"
@fruit = "melon"
@fruit ||= "orange"
=> "melon"
## boolean 케이스
@is_solved = false
@is_solved ||= true
=> true
@is_copied = true
@is_copied ||= false
=> true
- Class와 Module 의 차이는 무엇인가요?
- 여기 내용을 참고해서 공부 및 작성했습니다.
- 조건연산자 중 and 와 && 의 차이는 무엇인가요?
기능으로선 'and(그리고)'를 표현한다는 공통점이 있으나, 우선순위가 다릅니다.
&&
가 and
보다 우선순위가 높습니다.
foo = :foo
bar = nil
a = foo and bar
# => nil
a
# => :foo
a = foo && bar
# => nil
a
# => nil
a = (foo and bar)
# => nil
a
# => nil
(a = foo) && bar
# => nil
a
# => :foo
또한, 위 표현을 보면 and
표현은 =
표현 보다 약하단 것도 볼 수 있습니다.
a = foo and bar
# => nil
a
# => :foo
and 표현 같은 경우,=
이 먼저 실행된 후, 비교가 진행이 되는 반면
&&
는 비교 먼저가 진행되는게 보입니다.
a = foo && bar
# => nil
a
# => nil
- Block, Proc, Lambda 의 차이가 무엇인가요?
- block
· block은 중괄호({ ... }) 혹은 do-end 사이에 문법을 표현하는 방법입니다.
· block 코드를 만나는 즉시 실행됩니다.
for i in 0..3 do
puts i
end
4.times { |count| puts "#{count}" }
- Proc
· block 형태로 코드를 사전에 입력 후(이 때는 Proc 내부 코드 동작 안함; unactive), 나중에 Proc 변수가 호출되면 내부 코드가 동작(active)됩니다.
· 코드 재사용이 가능합니다.
arr = [1,2,3]
plus = Proc.new do |t|
t+t
end
=> #<Proc:0x007fba87392300@(irb):289>
result = Array.new
arr.each { |num| result << plus.call(num) }
=> [1, 2, 3]
result
=> [2, 4, 6]
· argument 갯수가 엄격하지 않습니다. (인자가 부족할 시, 해당 자리는 nil로 처리)
test_proc = Proc.new { |a,b,c| puts "#{a} #{b} #{c.class}" }
test_proc.call(1, 2, 3)
1 2 3
=> nil
test_proc.call(1, 2)
1 2 NilClass
=> nil
· Proc 내에서 return문을 만날 시, proc 내 return문이 반환됩니다. (아래 메서드는 결국 Proc의 return문을 반환)
def proc_return
Proc.new { return "Proc.new" }.call
return "proc_return method finished" # 실행하지 않는다.
end
puts proc_return
=> "Proc.new"
def generic_return(code)
one, two = 1, 2
three, four = code.call(one, two)
return "Give me a #{three} and a #{four}"
end
puts generic_return(lambda { |x, y| return x + 2, y + 2 }) #=> Give me a 3 and a 4
puts generic_return(Proc.new { |x, y| return x + 2, y + 2 }) #=> LocalJumpError: unexpected return
- Lambda
· block 형태로 코드를 사전에 입력 후(이 때는 Lambda 내부 코드 동작 안함; unactive), 나중에 Lambda 변수가 호출되면 내부 코드가 동작(active)됩니다.
· 코드 재사용이 가능합니다.
ex = lambda { |num| num - 30}
ex.call(40)
=> 10
· argument 갯수에 대해 엄격히 지킵니다. (argument 부족 시 ArgumentError: wrong number of arguments (given n, expected m)
)
test2 = lambda { |a,b,c| puts "#{a} #{b} #{c}" }
· Lambda 내에서 return문을 만나더라도 lambda는 계속 내부적으로 실행됩니다.
def lambda_return
lambda { return "lambda" }.call
return "lambda_return method finished" # 실행된다.
end
puts lambda_return
=> "lambda_return method finished"
def generic_return(code)
one, two = 1, 2
three, four = code.call(one, two)
return "Give me a #{three} and a #{four}"
end
puts generic_return(lambda { |x, y| return x + 2, y + 2 }) #=> Give me a 3 and a 4
puts generic_return(Proc.new { |x, y| return x + 2, y + 2 }) #=> LocalJumpError: unexpected return
- 외부 파일을 참조하는 require, load, include, extend의 차이는 무엇인가요?
- require : 최초 한번만 외부파일을 부르면 memory에 기록되고 계속 재사용 가능
- load : 한번 외부파일을 부르고, 코드가 종료되면 해당 파일도 종료 (일회성)
- include : Module 메소드를
인스턴스 메소드
로 상속받습니다. - extend : Module 메소드를
클래스 메소드
(self.*)로 상속받습니다.
## include와 extend의 차이점을 보여주는 코드
module Foo
def foo
puts 'heyyyyoooo!'
end
end
# include : 모듈메서드를 인스턴스 메서드로 상속받게 됨
class Bar
include Foo
end
Bar.new.foo # heyyyyoooo!
Bar.foo # NoMethodError: undefined method ‘foo’ for Bar:Class
# extend : 모듈메서드를 클래스 메서드로 상속받게 됨
class Baz
extend Foo
end
Baz.foo # heyyyyoooo!
Baz.new.foo # NoMethodError: undefined method ‘foo’ for #<Baz:0x1e708>
- clone과 dup, deep_dup의 차이는 무엇인가요?
- [Ruby] Clone VS dup
· clone은 원본 변수의 freeze 메소드 속성에 대해 가지고 있는 반면, dup은 아닙니다.
* freeze 메소드 : 해시의 값(value)이 변경되지 못하도록 명령하는 메소드
a = {'key1' => 1, 'key2' => {'key3' => 3, 'key4' => 4}}.freeze
b = a.clone
c = a.dup
a['key1'] = 32
=> RuntimeError: can't modify frozen Hash
b['key1'] = 32
=> RuntimeError: can't modify frozen Hash
c['key1'] = 32
=> 32
· 싱글톤 메소드에 대해서는 copy가 안됩니다.
* 싱글톤(singleton) 메소드 : 특정 객체에만 주어진 메소드
o = Object.new
def o.foo
42
end
o.dup.foo
=> NoMethodError: undefined method `foo'
o.clone.foo
=> 42
- [Rails] dup VS deep_dup
· deep_dup은 원본 데이터와 메모리 공유를 하지 않습니다.
a = {'key1' => 1, 'key2' => {'key3' => 3, 'key4' => 4}}
b = a.dup
c = a.deep_dup
a['key2'].object_id == b['key2'].object_id
=> true
a['key2'].object_id == c['key2'].object_id
=> false
[개인적인 의문] clone 메소드는 freeze 속성에 대해 그대로 가져간다는 특징이 있다보니, 아래와 같이 원본 Hash를 담고 있는 a
변수와 a의 freeze 속성까지 그대로 copy해낸 b
변수는 Hash 값 변경을 시도 시 변경이 안되는 것을 확인할 수 있었습니다.
a = {'key1' => 1, 'key2' => {'key3' => 3, 'key4' => 4}}.freeze
b = a.clone
c = a.dup
a['key1'] = 32
# => RuntimeError: can't modify frozen Hash
b['key1'] = 32
# => RuntimeError: can't modify frozen Hash
c['key1'] = 32
# => 32
하지만 a와 b의 메모리에 대해서도 공유하는지 궁금해서 이를 조회해 보면 변수 자체는 서로 다른 값을 가지나, hash 내 key는 메모리를 공유한다는 것을 알 수 있습니다.
a.object_id ## original
=> 70219554622880
b.object_id ## clone
=> 70219554589820
a['key1'].object_id ## original
=> 3
b['key1'].object_id ## clone
=> 3
c['key1'].object_id ## dup
=> 65
'아니, 변수에 대한 주소값을 공유한다며??' 저는 여기서 혼동을 느꼈습니다.
그래서 저는 스택오버플로우를 통해 이에대해 질문을 넣었고, 여기서 답을 얻을 수 있었습니다.
[의문에 대한 정답] integer 형태의 value는 값만 동일하다면 서로 메모리를 공유한다는 특징이 있었습니다.
x = 3
y = 3
x.object_id == y.object_id # true
x = "a"
y = "a"
x.object_id == y.object_id # false
하지만 만약 아래와 같이 범위가 매우 큰 숫자를 초기화 할 경우, 아래 숫자는 메모리를 서로 공유하지 않습니다.
x = 11111111111111111111111111111111
y = 11111111111111111111111111111111
x.object_id == y.object_id # false
- Rails의 2가지 주요 철학이 무엇이며 각 철학의 예시가 무엇인가요?
- DRY(Don't Repeat Your Self): '코드를 반복적으로 쓰지 마라' 라는 일환으로서 코드의 재사용을 강조합니다.
[예시] 동일한 SQL 역할을 수행하는 메소드에 대해 Model에서scope
를 통해 별도의 메소드를 정의 및 이를 재사용 함으로서 코드의 반복을 줄임.
class Bulletin < ApplicationRecord
scope :find_bulletin, -> (bulletinId) { find(bulletinId) }
end
- COC(Convention Over Configuration): '설정보단 규약' 이란 조건으로서, 최대한 Rails에서 정해진 규칙을 활용하는 것
[예시] MVC의 패턴에 있어 Model과 Controller의 이름을 정의함에 있어 다음 규칙이 (암묵적으로) Rails 내에서 지켜지고 있습니다.
1) Controller : bulletins_controller.rb
2) Model : bulletin.rb
--api
옵션을 사용하여 Rails 프로젝트를 만들었을 때 어떤 middleware 변화가 있나요?
- 기존의 Browser Application에 사용됐던 미들웨어 생성이 안됩니다. (쿠키 관리 미들웨어 생성 x 등)
- view, helper, asset 생성이 제한됩니다.
- Controller에서는 기존의 view가 함께 쓰였던 때 당시
ActionController::Base
가 아닌ActionController::API
을 상속받습니다. - API 환경의 프로젝트 생성 시, 아래의 Middleware가 기본으로 적용됩니다.
(view에서 쓰였던 미들웨어는 배제된 채로 생성됩니다.)
Rack::Sendfile
ActionDispatch::Static
ActionDispatch::Executor
ActiveSupport::Cache::Strategy::LocalCache::Middleware
Rack::Runtime
ActionDispatch::RequestId
Rails::Rack::Logger
ActionDispatch::ShowExceptions
ActionDispatch::DebugExceptions
ActionDispatch::RemoteIp
ActionDispatch::Reloader
ActionDispatch::Callbacks
Rack::Head
Rack::ConditionalGet
Rack::ETag
- Rails(ActiveSupport Extensions) 에서 추가된 Array, Hash Class의 함수는 어떤 것들이 있나요?
- Array
-
Accessing
- from : n을 skip한 이후로 부터 배열 조회
- to : m까지의 배열을 조회
- second, third, fourth, fifth, second_to_last : n번 째 혹은 n부터 m까지 범위의 배열 조회
-
Extracting
- extract! : block 내에 표현된 코드를 기반으로 배열 추출
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9] numbers # => [0, 2, 4, 6, 8]
-
Conversions
- to_sentence : 배열 항목을 열거하는 문장을 포함하는 문자열로 바꿉니다.
%w().to_sentence # => "" %w(Earth).to_sentence # => "Earth" %w(Earth Wind).to_sentence # => "Earth and Wind" %w(Earth Wind Fire).to_sentence # => "Earth, Wind, and Fire"
- to_formatted_s : 문자가 formatting 될 형식을 지정합니다, default는
to_s
입니다. - to_xml : 배열을 XML 형식으로 반환합니다.
-
Wrapping
- Array.wrap : Array가 아닌 문자를 배열 type으로 감싸줍니다.
Array.wrap(nil) # => [] Array.wrap([1, 2, 3]) # => [1, 2, 3] Array.wrap(0) # => [0]
-
Duplicating
- deep_dup : Active Support를 통해 자체 및 모든 객체를 재귀적으로 복제합니다. 내부의 각 객체에 메소드를 Array#map으로 보내는 방식과 동일합니다. (변수 간 메모리 공유를 안합니다.)
array = [1, [2, 3]] dup = array.deep_dup dup[1][2] = 4 array[1][2] == nil # => true
-
Grouping
- in_groups_of(number, fill_with = nil) : 배열을 size을 기준으로 분할, 그룹화 된 배열을 반환합니다.
[1, 2, 3].in_groups_of(2) # => [[1, 2], [3, nil]] [1, 2, 3].in_groups_of(2, 0) # => [[1, 2], [3, 0]] [1, 2, 3].in_groups_of(2, false) # => [[1, 2], [3]]
- in_groups(number, fill_with = nil) : %w(괄호안에 있는 다수의 문자열을 배열로 변환) 표현식을 활용해서 특정 수의 그룹으로 분할, 그룹화 된 배열을 반환합니다.
%w(1 2 3 4 5 6 7).in_groups(3) # => [["1", "2", "3"], ["4", "5", nil], ["6", "7", nil]] %w(1 2 3 4 5 6 7).in_groups(3) {|group| p group} ["1", "2", "3"] ["4", "5", nil] ["6", "7", nil]
- split(value = nil) : split value를 기준으로 배열 내 element를 분할합니다.
[0, 1, -5, 1, 1, "foo", "bar"].split(1) # => [[0], [-5], [], ["foo", "bar"]] (-5..5).to_a.split { |i| i.multiple_of?(4) } # => [[-5], [-3, -2, -1], [1, 2, 3], [5]]
-
- Hash
- Conversions
- to_xml : 해시를 XML 형식으로 반환합니다.
- Merging : 서로 다른 Hash를 합칩니다.
- reverse_merge and reverse_merge! and reverse_update
- deep_merge and deep_merge! : 기존의 해시에서 key를 찾아내고, 이미 Key가 존재할 경우 기존의 객체를 유지하고 또다른 Hash와 합병됩니다.
{a: {b: 1}}.deep_merge(a: {c: 2}) # => {:a=>{:b=>1, :c=>2}} {a: {b: 1}}.merge(a: {c: 2}) # => {:a=>{:c=>2}}
- Deep duplicating
- deep_dup : Active Support를 통해 자체 및 모든 객체를 재귀적으로 복제합니다. 내부의 각 객체에 메소드를 Enumerator#each_with_object 으로 보내는 방식과 동일합니다. (변수 간 메모리 공유를 안합니다.)
hash = { a: 1, b: { c: 2, d: [3, 4] } } dup = hash.deep_dup dup[:b][:e] = 5 dup[:b][:d] << 5 hash[:b][:e] == nil # => true hash[:b][:d] == [3, 4] # => true
- Conversions
- save, save! 함수의 동작 차이는 무엇이며 각각 어떤 상황에서 사용하나요?
- save : 데이터 저장과정 도중 오류(invalid) 발생 시, 결과에 대해
boolean
으로 반환합니다. - save! : 데이터 저장과정 도중 오류(invalid) 발생 시, 에러를 일으키고,
raise error
메세지를 반환합니다.
- find_by!(a: ‘b’) 와 where(a: ‘b’)의 차이는 무엇인가요?
- find_by! : 데이터를 탐색 후 여러개 나온 결과물 중
하나
만을 반환합니다. 탐색 결과물이 없을 시에러
를 일으킵니다. - where : 데이터를 탐색 후 여러개 나온 결과물
전체
를 반환합니다. 탐색 결과물이 없을 시nil
을 반환합니다.
- update, update_all, update_attributes, update_columns 의 차이는 무엇인가요?
- update_attributes : Rails 4.0.2 부터 update 메소드로 alias 처리되었습니다.
- update : 1개 단위로 데이터 수정이 이루어지며, validation 검증이 통과되면 데이터가 수정됩니다.
- update_columns : 1개 단위로 데이터 수정이 이루어지며, 콜백검증 없이 데이터베이스에 바로 데이터가 수정됩니다.
- update_all : n개 단위로 데이터 수정이 이루어지며, 콜백검증 없이 데이터베이스에 바로 데이터가 수정됩니다.
- destroy, delete의 차이는 무엇인가요?
- 데이터가 삭제되기 전
destroy
은 콜백 검사를 하나,delete
는 콜백 검사를 생략합니다. destroy
메소드를 통해 삭제 시, 외래키로 연계된 자식(child) 데이터도 삭제됩니다.
- ActiveRecord Validation 함수들의 공통 옵션은 어떤게 있나요?
- allow_nil : nil 값 검사
- allow_blank : 공백('') 및 nil 값 검사
- message : Exception 상황 발생 시 에러메세지를 띄웁니다.
- has_many :thorugh 와 has_and_belongs_to 의 차이는 무엇인가요?
- has_many :thorugh : 2개의 Model 사이에 Join테이블을 두고, join 테이블에 2개의 테이블 외래키 컬럼을 참조해서 타 테이블을 읽어내어 데이터를 읽어오는 방식
- has_and_belongs_to : 2개의 Model과 또 다른 제 3자의 Model을 두고, 3자 모델에서는 2개의 테이블 외래키의 컬럼은 기본적으로 가지고있고, 더불어 추가적인 컬럼을 가지고 있을 수 있음. 제 3자 Model이 가진 2개의 외래키를 기반으로 M:N 참조 또한 가능
- Rails 서버 실행 시 우선적으로 자동 실행되어야 할 코드는 일반적으로 어디에 위치해야 하나요?
config 폴더 내에 위치되어있습니다.
- ActiveModel에 대해 length, count, size 각각의 차이는 무엇인가요?
- length : 모든 Attribute(select *)를 탐색 후, 데이터 갯수를 알아냅니다.
- count : Count 함수를 통해 데이터 갯수를 알아냅니다.
- size : 테이블에 counter cache 컬럼을 먼저 찾아보구, 없을 경우
count
메소드와 동일한 역할을 수행합니다.
- HTTP GET 요청 시 ActionController에서 인식하는 Array 와 Hash 파라미터 구조는 어떻게 되나요?
- Array
GET /users?ids[]=1&ids;[]=2&ids;[]=3
=> params[:ids] = ["1", "2", "3"]
** Hash
<form accept-charset="UTF-8" action="/users" method="post">
<input type="text" name="user[name]" value="Auction" />
<input type="text" name="user[phone]" value="201-867-5309" />
<input type="text" name="user[address][postcode]" value="07001" />
<input type="text" name="user[address][city]" value="New Jersey" />
</form>
=> params[:user] = { "name" => "Auction", "phone" => "201-867-5309", "address" => { "postcode" => "07001", "city" => "New Jersey" } }
- rescue와 rescue_from 의 차이는 무엇인가요?
- rescue : 특정 Controller Action 내에서만 실행되는 에러 핸들러
- rescue_from : Controller에서 사전에 에러를 다루는 Action을 생성 후, 모든 Action 내 코드에서 동작 중 에러 발생 시 rescue_from 규칙에 맞는 Action가 실행되는 에러 핸들러
- rescue는 일부 Action만을 책임진다면, rescue_from은 Action 전체를 책임짐.
- Resource Routing 설정 시 resources 와 resource 의 결과가 어떻게 다른가요?
- Browser 환경의 Application
- resources :
index, show, new, create, edit, update, destroy
7가지 규칙이 생성되며,show, edit, update, destroy
에는 각각 특정 ID값을 가지고 있습니다. - resource :
show, new, create, edit, update, destroy
6가지 규칙이 생성되며, 특정 ID값을 가지고 있지 않습니다.
- resources :
- API Only Application
- resources :
index, show, create, update, destroy
5가지 규칙이 생성되며,show, update, destroy
에는 각각 특정 ID값을 가지고 있습니다. - resource :
show, create, update, destroy
4가지 규칙이 생성되며, 특정 ID값을 가지고 있지 않습니다.
- resources :
- Resource Routing 설정 시 namespace 와 scope, nested resources 각각의 차이는 무엇인가요?
- namespace : 기존의 URL 패턴에 추가적으로 하위 Path가 생기고, Controller에 있어 하위 폴더를 거치게 됨.
namespace :admin do
resources :articles, :comments
end
- scope : Controller은 기존의 resource(s) 방식으로 가리키되, Path는 namespace 방식으로 변경하고 싶을 경우
scope '/admin' do
resources :articles, :comments
end
## 위 표현과 동일한 문법
resources :articles, path: '/admin/articles'
- nested resources : resources 안에 또 resources가 있는 개념으로서, RESTful API 규칙을 자동으로 생성해줍니다.
resources :magazines do
resources :ads
end
- Resource Routing 설정 시 concern 은 어떤 용도로 사용하나요? 블록 내 공통되는 여러개의 라우터 설정을 하나로 묶어서 정의할 때 사용
- member route와 collection route 의 차이는 무엇인가요?
- collection : 하나의 객체를 다루는 액션
- member : 여러 개의 객체를 다루는 액션
- Active Job은 무엇이며 Global ID는 무엇인가요?
- Active Job : 서버에서 Background Job으로 어떤 작업에 대한 실행이 이루어지며, 동기(perform_now) 및 비동기(perform_later) 방식이 있습니다.
- Global ID : Active Job에서 지원되는 매개 변수, 이를 통해 class/ID 쌍 대신 작업중인 Active Record 개체를 Job에 전달할 수 있습니다.
- soft delete가 무엇이며 Rails에서 어떻게 구현할 수 있나요?
- 기존의 테이블에서
deleted_at
과 같은 컬럼을 하나 추가 후, 데이터가 삭제되더라도 완전히 삭제되진 않고deleted_at
에 삭제 trigger가 발동된 날짜를 기록하고,deleted_at
이 nil이 아닌 경우 사용자가 보는 화면에서는 해당 데이터를 (삭제된 것 처럼) 숨깁니다. (후에 데이터 복구 가능) - Gem을 통해 간단히 구현해낼 수 있습니다 : acts_as_paranoid
- counter_cache 옵션은 무엇인가요?
테이블이 가진 Association 데이터(자식 데이터)가 추가/제거될 때 마다 증감률에 대해 따로 부모테이블 컬럼에 기록을 하는 옵션입니다. (이를 size
메소드와 엮어서 활용할 수 있습니다.)
- 평소에 N+1 문제를 예방할 수 있는 방법은 무엇이 있을까요?
n개 이상의 테이블을 참고해야 함에 있어, 사전에 테이블을 참조하거나(preload 혹은 includes), Join 처리(eager_load 혹은 includes)
- includes, preload, eager_load 는 각각 어떤 차이가 있나요?
- preload : (테이블이 n개일 때) 사전에 참조해야 하는 테이블 n개를 조회 및 탐색 수행
- eager_load : 1개의 쿼리만을 가지고 Left Outer Join을 통해 SQL 쿼리 탐색을 수행
- includes : eager_load, preload 둘 다의 속성을 가지고 있습니다 / SQL에서 WHERE Query 사용 시 eager_load 방식으로 탐색
- ActiveSupport::Concern은 어떤 용도로 사용하나요?
- 클래스메소드 → 인스턴스 메소드로 할당됩니다.
- 모듈을 상속합니다.
- 문법이 코드 의존성을 강하게 하다보니 효율이 떨어진다는 의견이 있습니다.
module M
def self.included(base)
base.extend ClassMethods
base.class_eval do
scope :disabled, -> { where(disabled: true) }
end
end
module ClassMethods
...
end
end
require 'active_support/concern'
module M
extend ActiveSupport::Concern
included do
scope :disabled, -> { where(disabled: true) }
end
class_methods do
...
end
end
- 알아두면 도움이 되는 55가지 루비 기법
- ActiveRecord는 어떻게 Database의 컬럼과 매핑할까?
- Ruby Metaprogramming Is Even Cooler Than It Sounds
- 루비 메타프로그래밍(1) - Object Model
- Ruby Meta-programming
- Class와 Module의 차이점
- ||= 문법 개념
- PROCS, LAMBDA, BLOCKS
- 외부 파일을 참조하는 require, load, include, extend의 차이
- Ruby Methods: differences between load, require, include and extend in Ruby
- What's the difference between Ruby's dup and clone methods?
- (루비 사용자 가이드) 싱글턴 메소드
- Active Support Core Extensions
- Rails Paperclip: update vs. update_attributes
- Difference between update, update_columns, update_column, update_attributes, assign_attributes
- ActiveSupport::Concern code placed inside the included block or in the module body
- How to use concerns in Rails 4
- (제타위키) N+1 쿼리 문제
안녕하세요
collection : 하나의 객체를 다루는 액션
member : 여러 개의 객체를 다루는 액션
가 반대로 써져있어서 씁니다~
https://tadhao.medium.com/member-vs-collection-in-rails-routes-ade10c8c5d19
여튼 너무 잘 봤어요. 많이 배웠습니다. 감사합니다!