> For the complete documentation index, see [llms.txt](https://simian114.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simian114.gitbook.io/blog/undefined-1/diary/2020/12/20201228.md).

# 20201228(월)

## 2020-12-28

### 1. 학습 날짜

* 2020-12-28

### 2. 학습 시간

* 09:30 \~ 21:00

### 3. 학습 범위 및 주제

* 루비온레일즈 모델, 컨트롤러

### 4. 학습 목표

* 페펙트 루비 온 레일즈 5, 6장

### 5. 과제 제출

* x

### 6. 상세 학습 내용

* 모델
  * 트랜잭션: 트랜잭션이란 모델에 관한 명령을 여러개 묶어서 한번에 처리하는 것이다. 트랜잭션이 왜 필요한지 알기 위해서는 예시를 생각해보는게 편함.
    1. 내 계좌에서 돈을 출금
    2. 친구의 계좌로 돈을 입금
  * 위와 같은 상황이 있을 때, 트랜잭션을 사용하지 않으면 1번이 실패했는데 2번을 수행하는 어처구니 없는 일이 발생할 수 있다.
  * 트랜잭션은 한꺼번에 처리하는 것으로, 만약 트랜잭션이라는 스코프에서 하나라도 명령이 실패하면 전부 없었던 일로 되돌려버린다. 이를 롤백이라고 한다.
  * 만약 모든 명령이 성공했다면, 트랜잭션을 빠져나오는 시점에 커밋을 한다. (롤백의 반대라고 생각하면 됨)
  * 트랜잭션 분리 레벨
    * 서버는 하나의 요청만 처리하지 않는다. 여러 요청을 한번에 처리한다. 즉 동일한 데이터에 대해서 트랜잭션이 동시에 여러 프로세스에서 실행될 수 있다.
    * 분리레벨이란 여러 개의 트랜잭션을 동시 실행한 경우에 동작을 표시하는 것이다.
    * 분리레벨이 높으면 데이터의 정합성은 높아지지만 실행성은 낮아진다(정확성이 높아지고 실행성이 낮아짐)
    * 왜그러냐하면 분리레벨이 높으면 쓰레드에서 공유 자원을 뮤텍스 걸어면 다른 쓰레드는 뮤텍스 락이 풀릴 때 까지 기다리듯이 트랜잭션 또한 분리레벨이 높으면 트랜잭션이 완전히(또는 부분적으로 - 분리 레벨 낮음) 끝날 때 까지 기다려야 하므로 동시 실행성이 낮아진다는 것. 반대로 완벽해질 때 까지 기다리니깐 데이터의 정확성은 높아진다.
    * 여러 개의 트랜잭션에서 생길 수 있는 문제는 3개로 나눌 수 있다. 비커밋 읽기, 비반복 읽기, 가상 읽기
  * 옵티미스틱 동시 실행 제어
    * 웹어플리케이션은 여러 사용자가 동일한 레코드를 동시에 수정하는 상황이 자주 발생한다.
    * 사용자A가 data의 값을 100에서 150으로 수정한다. 동시에 사용자B가 데이터를 추출하고 변경한다고 하자. 이 때 B가 추출한 data는 100이었다. 따라서 B는 이 값을 150으로 증가 시키기 위해 + 50을 한다. 그런데 A가 먼저 50을 증가시키고, B가 증가시켰기 때문에 데이터는 50 씩 두번이 증가하고 결과적으로 200이 되어버린다. 이는 사용자들이 의도하지 않았던 결과다.
    * 이 문제를 해결하기 위해 rails는 옵티미스틱 동시 실행 제어 라는 기능을 갖고 있다. 이 기능을 사용하기 위해서는 lock\_version이라는 컬럼을 추가하면 된다.
    * lock\_version은 이름 그대로 `버전`을 `lock` 시키는 것이다. 사용자A가 값을 추출 했을 때 버전이 0이고 data가 100, 동시에 사용자 B가 data를 추출했을 때 버전이0이고 data가 100 이라고 해보자. 이 상태에서 A가 먼저 data의 값을 50 증가시켜서 150으로 만든다. 그러면 data의 버전은 1, data는 150이 된다. 이 상태에서 사용자B가 data의 값을 증가시키고 저장하려고 하면 예외가 발생한다. 왜냐? A의 명령으로 data의 버전은 1이되었는데, B가 증가시키는 data의 버전은 0이었기 때문.
* Association으로 여러 개의 테이블 처리
  * Association이란 테이블 사이의 관계를 모델의 관계로 조작할 수 있도록 하는 구조다. Assoc을 사용하면 여러 테이블에 겹쳐 데이터 조작을 손쉽게 할 수 있다.
  * books 테이블의 레코드 하나 Book 인스턴스에는 0개 이상의 리뷰가 올 수 있다.
  * 반대로 하나의 Review 인스턴스는 Book에 속하게 된다.
  * 이 관계를 표현하면 Book은 review를 `has_many` 하고 review는 book 에 `belongs_to`된다.
  * `user`는 `authro`가 될 수 있고 `author`은 `user`다. 즉 1:1의 관계가 되는 것.
  * 이런식으로 `has_many`, `belongs_to` 등등의 코드를 사용하면 자동으로 여러 메서드가 생성된다.
  * 예를 들어 book 인스턴스는 `@book.reviews` 처럼 원래 `book` 에 존재하지 않는 속성인 `reviews` 메써드를 사용할 수 있게 된다. 이 모든것이 단 한줄만 입력하면 되는 것임.
* 콜백 메서드
  * 콜벡 메서드란 모델을 조작할 때 함께 실행할 철를 콜백으로 정의하여 사용하는 것이다. 예를 들면 아래와 같다.
  * 사용자 정보를 등록할 때, 비밀번호가 지정되지 않았다면 임의의 비밀번호를 생성한다.
  * 도서 정보를 제거한 뒤, 삭제 이력을 저장한다.
  * 저자 정보를 제거할 때 파일 시스템으로 관리하고 있는 섬네일 이미지도 함께 제거한다. 등등
* 마이그레이션
  * 마이그레이션은 db를 생성하고 변경했을 때 이를 어플리케이션의 db에 실제로 적용할 수 있게 만들어 주는 기능이다.
  * 기본적으로 db 폴더 안에 여러개의 마이그레이션 파일들이 존재하고 이 파일들을 `rake db:migrate`로 마이그레이션 하면 데이터들이 `schema.rb`에 적용된다. 만약 새롭게 migrate 파일을 만들거나 수정하고 `rake db:migrate` 를 하게 된다면 마이그레션 폴더안에 존재하는 마이그레이션 파일과 스키마를 비교해서 업데이트 한다.
* 컨트롤러
  * 컨트롤러의 역할은 두가지다. 첫 째는 요청 정보 추출, 둘 째는 응답의 생성
  * 클라이언트가 params로 요청정보를 보냈을 때 이 데이터으 종류는 총 세가지다. 1 포스트 데이터, 2. 쿼리 정보, 3. 라우트 매개 변수

### 7. 오늘 학습 내용에 대한 개인적인 총평

* 요즘들어 학습에 질이 많이 떨어진 것을 느끼고 있다. 연말이라고 해서 이렇게 나태해지면 안되는데.... 다시 추스리고 열심히 해야겠다.

### 8. 다음 학습 계획

* 루비온레일즈 5,6 장 복습, 7장 진도
