루비온레일즈 스터디
루비 온 레일즈 스터디 내용을 핵심적으로 요약하여 궁금증을 해소하고 학습에 도움을 드립니다.
Ruby
1. symbol과 string의 차이는 무엇인가요?
- symbol 은 immutable 하지만, string 은 mutable 하다.
- 메모리 상에서도, symbol은 immutable 하기 때문에 같은 값을 지닌 심볼이 같은 주소를 가리키지만, string 은 그렇지 않다.
- 대부분의 경우, 심볼을 사용하는 것이 문자열보다 더 메모리나 성능 측면에서 효율적이다.
2. self 는 무엇인가요?
- 루비에서의 self 는 현재의 Class 나 모듈을 나타낸다. self 가 들어간 함수는 클래스 함수가 되고, 그렇지 않은 함수는 인스턴스 함수가 된다.
- 클래스 함수가 아닌 함수 내부에서 self 가 사용되면, 그 때에는 인스턴스 그 자체를 의미한다.
3. 생성자(constructor)을 사용하는 방법은 무엇인가요?
- 클래스에서 initialize 함수를 만든다. 이 때 @variable 은 인스턴스 변수, @@variable 은 클래스 변수를 의미한다. 또한 인스턴스 변수에 read 기능만 주고 싶을 때에는 attr_reader :variable, 변경도 가능하게 하기 위해서는 attr_accessor 추가
4. Ruby가 dynamic programming language 임을 나타내는 특징들은 무엇인가요?
- 런타임시에 클래스에 멤버 변수, 메서드 추가 삭제 재정의 등이 가능
class_eval “def #{str}; @#{str}; end”
class_eval “def #{str}=(value); @#{str}=value; end”
5. 동적인 함수명을 실행(invoke) 하는 방법을 설명하세요.
-a = [1,2,3]
a.send(‘length’)
-FileUtil.send(‘pwd’)
- def load()
puts ‘test’
end
send(‘load’)
6. ||= 의 역할은 무엇인가요?
- a ||= b의 경우, a가 falsy value일 경우, a에 b를 할당
7. Class와 Module 의 차이는 무엇인가요?
- 클래스는 초기화(initialize) 될 수 있지만, 모듈은 그렇지 않다. 모듈은 메소드들의 라이브러리이다.
8. 조건연산자 중 and 와 && 의 차이는 무엇인가요?
- 기능상 동일하나 and가 우선순위가 낮음
9. Block, Proc, Lambda 의 차이가 무엇인가요?
- Proc : 익명함수(절차)를 담은 객체, .call()을 통해 호출가능 (기명함수와 차이가 존재). 메소드 안에 return 이 있으면 해당 메소드 전체를 return 하여 빠져나온다.
- Lambda : Proc 객체를 생성하는 방법, 인자 개수 준수, return과 break가 익명 함수 안으로 한정
- Block : do ~ end 사이의 코드, 메서드에 블록을 넘겨주면 yield로 실행 가능, &operator를 통해 지역 변수 대신 블록에 대한 참조를 인자로 전달 가능, return과 break가 블록 안으로 한정
Proc : Procedure, 코드의 일련을 하나의 값으로 묶어놓은 객체
(함수 인자의 개수를 체크하지 않는다.)
Lambda : Proc을 생성하는 방법. Lambda로 생성하면 파라미터 개수를 체크한다.
- lambda는 diminutive return을 할 수 있다는 점이다. 예컨데, Proc는 값을 반환하면 메서드를 중단한다. 따라서 메서드의 최종 반환 값은 Proc의 반환값이 된다. 하지만 lambda는 반환 후에도 메서드가 계속 된다.
https://www.joinc.co.kr/w/Site/Ruby/ProcsLambdaBlocks
10. 외부 파일을 참조하는 require, load, include, extend의 차이는 무엇인가요?
-load는 매번 새롭게 파일을 불러옴
-require는 최초 한 번만 파일을 불러옴
-include는 모듈의 메서드들을 인스턴스 메서드로 불러옴
-extend는 모듈의 메서드들을 클래스 메서드로 불러옴
11. clone과 dup, deep_dup의 차이는 무엇인가요?
- clone은 object 및 내부 상태를 복사하지만, dup는 새로운 인스턴스를 반환받음
- While clone is used to duplicate an object, including its internal state, dup typically uses the class of the descendant object to create the new instance.
- clone/dup의 shallow copy와 달리, deep_dup는 deep copy가 가능함
category2 = category.dup
#=> #<Category id: nil, name: "Favorites">
category2 = category.clone
#=> #<Category id: 1, name: "Favorites">
deep_dup : 복사하고, 그 객체에 포함된 attribute 까지 복사
Rails
1. Rails의 2가지 주요 철학이 무엇이며 각 철학의 예시가 무엇인가요?
같은 것을 반복하지 말 것(Don't Repeat Yourself: DRY)
설정보다 규정을 우선한다(Convention Over Configuration) : Scaffold 의 라우팅 규칙, 컨트롤러, 모델파일 이름의 네임 컨밴션
2. - -api 옵션을 사용하여 Rails 프로젝트를 만들었을 때 어떤 middleware 변화가 있나요?
1 - The api app is configured to start with a more limited set of middlewares than normal. Specifically, it will not include any middleware primarily useful for browser applications (like cookies support) by default
2 - In the api app, ApplicationController inherits from ActionController::API instead of ActionController::Base. As with middlewares, this will leave out any Action Controller modules that provide functionalities primarily used by browser applications.
3 - The api app is configures the generators to skip generating views, helpers and assets when you generate a new resource.
You can always convert your rails app from either one of these to the other one. To do so, follow the steps in the reference I mentioned above.
=> cache middleware,
sendfile middleware,
Actiondispatch::Request (params),
Flash middleware
3. Rails(ActiveSupport Extensions) 에서 추가된 Array, Hash Class의 함수는 어떤 것들이 있나요?
https://guides.rorlab.org/active_support_core_extensions.html#accessing
4. save, save! 함수의 동작 차이는 무엇이며 각각 어떤 상황에서 사용하나요?
save! 명령어가 수행되지 않으면 Exception을 발생시킨다. (디버깅할 때 편리)
save 명령어가 수행되고 나면 그 값에 따라 boolean 값이 return 됨
5. find_by!(a: ‘b’) 와 where(a: ‘b’)의 차이는 무엇인가요?
find : 못찾으면 exception 발생,
find_by : 가장 처음 탐색된 레코드 반환(exception 발생하지 않고 nil 반환),
where: 모두 반환
6. update, update_all 의 차이는 무엇인가요?
- update : 한 개 이상의 레코드의 value를 모두 업데이트. 모델 validation 적용
- update_all : 조건에 맞는 레코드의 값들을 모두 업데이트. 모델 validation 적용x
7. destroy, delete의 차이는 무엇인가요?
- destroy: callback 호출됨, delete : callback 호출되지 않음
8. ActiveRecord Validation 함수들의 공통 옵션은 어떤게 있나요?
- validates :name, presense: true(존재)
- validates :allow, acceptance: true 체크박스에서 수락
- validates :password, confirmation: true (비밀번호, 비밀번호 확인)
- validates :subdomain, exclusion: { in: %w(www us ca jp),
message: "%{value} is reserved."}
- validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
message: "only allows letters"}
- validates :name, length: { maximum: 2 }
- validates :points, numericality: true
- validates :game_played, numericality: { greater_than: 2 }
- validates :email, uniqueness: true
9. has_many :thorugh 와 has_and_belongs_to 의 차이는 무엇인가요?
- has_and_belongs_to 는 단순히 연관 테이블로서만 기능을 할 때 생성한 후 , has_and_belongs_to 로 선언한다.
- has_many :through 는 이것 외에도 활용할 때 사용한다. (다른 레코드들 존재)
10. Rails 서버 실행 시 우선적으로 자동 실행되어야 할 코드는 일반적으로 어디에 위치해야 하나요?
- config/application.rb 에 위치시키면 된다.
11. ActiveModel에 대해 length, count, size 각각의 차이는 무엇인가요?
- count : sql 쿼리문에서의 레코드 개수를 반환한다. count 메소드를 사용할 때마다, 새로운 sql 쿼리문이 실행되게 된다.
- length : 레코드들이 로드된 상태이면, 새로운 메모리에 있는 정보를 사용하고, 새로 쿼리를 날리지 않는다. (잘못 사용하면 메모리를 많이 사용하게 될 수도 있다.)
- size : 레코드들이 로드되어 있으면, 새로운 쿼리를 날리지 않고, 그렇지 않으면 새로운 쿼리를 날린다.
12. HTTP GET 요청 시 ActionController에서 인식하는 Array 와 Hash 파라미터 구조는 어떻게 되나요?
13. rescue와 rescue_from 의 차이는 무엇인가요?
- rescue : try, catch 구문처럼 단일 구문에서의 예외처리를 도와준다.
- rescue_from : 일일이 예외처리 해 줄 필요 없이, 한 컨트롤러에서 해당 이슈를 모두 처리할 수 있다.
14. Resource Routing 설정 시 resources 와 resource 의 결과가 어떻게 다른가요?
- resources : index, new, create, edit, update, destroy
- resource : new, create, edit, update, destroy
- resources :posts, except: :index 와 동일
15. Resource Routing 설정 시 namespace 와 scope, nested resources 각각의 차이는 무엇인가요?
https://devblast.com/b/rails-5-routes-scope-vs-namespace
- namespace : 단순히 앞에 uri를 한칸 추가한다. (컨트롤러도 이에 따라 두 단계로 들어가야 한다.)
- scope : uri 앞에 한 칸 추가시키지만, 컨트롤러는 nested 된 구조가 아니어도 된다.
- path : 단순히 앞에 하나의 uri 계층의 이름을 customize (admin을 다른 이름을 바꿀 수 있다.)
- nested namespace : show 에 각각의 id를 나타내는 uri가 나타남
16. Resource Routing 설정 시 concern 은 어떤 용도로 사용하나요?
https://rubyinrails.com/2019/04/23/rails-routes-concerns/
반복 가능한 route 구조가 반복될 때, 코드를 반복할 필요 없이, concern을 사용하면 된다.
(DRY)
17. member route와 collection route 의 차이는 무엇인가요?
- member : 중간에 :id 값을 params 로 받게 된다.
- collection : id 값지 않고 단순히 nested 된 uri를 지니게 된다.
18. Active Job은 무엇이며 Global ID는 무엇인가요?
- Concurrent 한 로직 처리를 위해서 제공되는 rails 의 기능. gem 으로는 sidekiq, delayed_job, resque 가 있다. (Queue를 이용한 Job scheduling을 통해 사용한다.)
- 회원가입 후 이메일 전송을 위해 사용됨
- globalId: Reference models by URI
One example is job scheduling. We need to reference a model object rather than serialize the object itself. We can pass a Global ID that can be used to locate the model when it's time to perform the job. The job scheduler doesn't need to know the details of model naming and IDs, just that it has a global identifier that references a model.
19. soft delete가 무엇이며 Rails에서 어떻게 구현할 수 있나요?
- Soft delete : 실제로는 삭제하지 않지만, delete 되었다고 DB 에 표시함으로써 서비스에서는 삭제한 것과 같은 효과를 냄
- gem을 이용한 방법 : paranoia 사용
- 수동으로 사용하는 방법
is_deleted: boolean 선언
모델 함수에 soft_delete 함수 만들기 , restore 함수도 만들어 준다.
20. counter_cache 옵션은 무엇인가요?
belongs_to 와 같이, 자식 레코드들의 수를 유지해야 될 때가 있다. 여기에서 count 보다 size를 이용하면 효율을 증대시킬 수 있다. (쿼리가 2번에서 1번으로 줄음) 그런데 counter_cache를 사용하면, 이 한 번의 쿼리수조차 아낄 수 있다. update, create 될 때마다 디비에 알아서 카운터 수가 변경된다.
post has_many :comments / post 에 comments_count 필드를 인티저로 생성 : comment.rb 에 counter_cache :comments_count 라고 선언
21. 평소에 N+1 문제를 예방할 수 있는 방법은 무엇이 있을까요?
https://zetawiki.com/wiki/N%2B1_%EC%BF%BC%EB%A6%AC_%EB%AC%B8%EC%A0%9C
- N+1 쿼리 문제 : 전체 리스트를 불러오는 데 1 번의 쿼리가 수행되고, 이와 연관된 테이블의 데이터를 얻기 위해 N번의 쿼리가 추가 수행되는 문제
- 해결 방안 : 두 테이블을 조인된 뒤에, 얻고 싶은 attribute를 호출하면, 쿼리 한번으로 원하는 바를 수행할 수 있다.
22. includes, preload, eager_load 는 각각 어떤 차이가 있나요?
https://mznetblog.wordpress.com/2016/04/29/includes-vs-eager_load/
https://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html
Yes. includes will load (1) all records of the parent and (2) all of the records referenced as arguments in the includes method.
Notice how using includes in the example below only triggers 1 additional query. Without includes, there would be an additional query to count the number of comments for every post:
Post.includes(:comments).map { |post| post.comments.size }
Post Load (1.2ms) SELECT "posts".* FROM "posts"
Comment Load (2.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" IN (1, 3, 4, 5, 6)
=> [3,5,2,4,2,1]
- eager_load : 하나의 긴 SQL 쿼리문이 생성된다.
- preload : 두 번의 쿼리문으로 해결
23. ActiveSupport::Concern은 어떤 용도로 사용하나요?
- 재사용가능한 클래스의 함수들을 모듈화해서 작성해 놓는 것. 주로 ~able로 이름짓는 것이 컨밴션이다. Vue.js 의 믹스인과 비슷하다고 말할 수 있다.
이것도 읽어보세요