티스토리 뷰
class PostsController < ApplicationController
## index 액션
def index
...
end
## show 액션
def show
...
end
## edit 액션
def edit
...
end
end
C는 Controller의 줄임말로서, Model을 가공을 담당하는 친구라고 보시면 됩니다.
또한 Controller는 여러개의 액션을 가지고 있고, 액션 내부에는 액션 이름에 대응되는 view에서 활용되는 변수 및 데이터를 처리하는 알고리즘들이 존재합니다.
- Controller은 Model과 View의 중간 경유지
Controller은 Model을 참고에서 테이블 내 데이터 탐색 정의를 하고, 이를 View에 넘기는 형식입니다.
- Controller 생성법
# rails g controller [컨트롤러 이름] [액션 리스트들...]
rails g controller posts index show create
Controller 생성 명령어는 다음과 같습니다.
위 명령어에 있어선
- posts : 컨트롤러 이름
- index, show, create : 컨트롤러를 이루는 액션
입니다.
해당 명령어를 통해 Controller 및 View 구성 파일들이 동시에 생성이 되고, routes.rb에 자동으로 URI 정의가 이루어집니다.
더불어 Controller에는 암묵적인 규칙이 있는데, 이름을 지을 때 '복수'명 으로 짓는걸 선호합니다.
-
Controller 사용 유의사항
Controller 사용에 있어 다음 규칙을 따릅니다.
1) 액션과 view의 이름은 일치하며, view는 액션 내 코드를 참고합니다.
2) 액션에 정의된 변수는 다른 액션 및 view에서 사용이 불가능 합니다.
3) Controller 내에서는 다른 Model을 호출할 수 있습니다.
## Post Controller에서 Comment 모델을 불러옴.
class PostsController < ApplicationController
def show
@comment = Comment.where(post_id: params[:id])
end
end
- before_action
액션 내 동작되는 코드에 있어 가끔 공통적으로 사용되는 코드를 하나로 묶고 싶은 때가 있습니다.
이를테면 게시물 열람/수정/삭제 때 공통적으로 쓰이는 id 탐색 입니다.
@post = Post.find(params[:id])
사실 이 코드는 다음과 같이 짜도 되긴 합니다.
class PostsController < ApplicationController
def index
@posts = Post.all
end
def show
@post = Post.find(params[:id])
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
@post.update(title: params[:title], content: params[:content])
end
def destroy
@post = Post.find(params[:id])
@post.destroy
end
end
하지만 저희는 before_action 을 이용해서 @post = Post.find(params[:id]) 코드를 하나로 묶어보겠습니다.
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
@posts = Post.all
end
def show
@post = Post.find(params[:id])
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
@post.update(title: params[:title], content: params[:content])
end
def destroy
@post = Post.find(params[:id])
@post.destroy
end
private
def set_post
@post = Post.find(params[:id])
end
end
위와같이 before_action을 이용해서 show, edit, update, destroy 액션만이 사전에 액션이 시작되기 전에 앞서 set_post 액션을 거치게 됩니다.
그런데 set_post 액션을 보면 특이하게 그 위에 private 이 있습니다.
private은 캡슐화를 정의한 것으로서, before_action 을 거쳐간 경우가 아니면 외부에서 접근이 안되도록 막습니다.
* 참고 : JAVA로 보는 private 캡슐화 개념 [클릭]
-
View 파일 내 Ruby/Rails 문법 사용
View 파일 내에는 Ruby/Rails 문법을 사용할 수 있는데, 그냥 사용하는것은 아닙니다.
예를들어 순수하게 Controller 액션에서 정의했던 변수를 사용하려면 다음과 같이 사용하면 됩니다.
1) 문법 사용 예제 1
## app/controllers/lotties_controller.rb
class LottieController < ApplicationController
def index
@random = (1..45).to_a # 1~45의 숫자가 담긴 배열을 생성합니다 (C언어로 치면 for (int i=1;i<=45;i++) 개념), 참고로 .to_a는 일반 정수를 array 화 시키는 메소드
@lotto = @random.sample(7).sort # random 변수 내 있는 1~45 숫자 중 .sample(n)를 통해 n개의 랜덤정수를 뽑아냅니다. 그리고 .sort를 통해 오름차순 정렬을 합니다.
end
end
## app/views/lotties/index.html.erb
<%= @lotto %>
하지만 변수만 쓰면 심심하겠죠?
view에서는 if문과 같은 전문적인 문법 사용에 대해서도 지원을 합니다.
2) 문법 사용 예제 2
## app/views/admins/index.html.erb
<% if current_user.has_role? :admin %>
<div>안녕하세요, 관리자 <%= current_user.nickname %>님!</div>
<% else %>
<div>해당 페이지는 접근 불가입니다.</div>
<% end %>
하지만 if문을 보면 뭔가 좀 이상합니다.
예제 1과는 다르게 = 가 없습니다.
결국 <% %> 내 = 의 여부는
<%= ... %> : 출력 결과물을 보여주는 것,
<% %> : 출력 결과물을 보여주지 않는 것
위 2개의 차이로 이해를 하면 됩니다.
덧붙여서, <%# %> 도 있는데, #가 들어가면 주석처리가 되어 외부 View 결과상으로는 아무런 동작도 하지 않고, 보여지지도 않습니다.
### app/views/homes/index.html.erb
## 정상적으로 코드가 view에 노출
<%= current_user.nickname %>
## 주석 처리 : 코드가 작동하지도, 노출되지도 않음.
<%# current_user.nickname %>
<%#= current_user.nickname %>
더불어, View 파일 내에서는 다음과 같이 모델을 직접 참고해서 데이터를 불러올 수 있긴 하나, 해당 방법은 미래의 코드 유지보수에 있어 추천을 드리지 않습니다.
1) 올바른 코드 작성 예
## app/controllers/posts_controller.rb
class PostController < ApplicationController
def index
@posts = Post.all
end
end
## app/views/homes/index.html.erb
<% @posts.each do |t| %>
<%= t.title %> / <%= t.content %>
<% end %>
참고 each do 문법은 변수가 가진 범위 만큼 반복을 돌면서 하나하나 데이터를 뽑아낼 때 쓰입니다.
(t라는 변수는 상속변수로서, 상세적으로 테이블의 컬럼(현재 예시에서는 title, content)을 가공할 때 쓰입니다.)
2) 올바르지 않은 코드 작성 예
* 작동은 잘 되긴 하나, 먼 미래에 유지보수 때 코드 찾느라 골 때릴 수 있음.
## app/views/homes/index.html.erb
<% Post.all.each do |t| %>
<%= t.title %> / <%= t.content %>
<% end %>
-
View와 Controller 중 누가 먼저 작동될까?
한번 이런 의문점을 가진적이 있었는데, 확인 결과 Controller을 먼저 거치고, 그 후에 View의 결과를 보여주는 구조였습니다.
확실한 답을 결정짓는 코드는 바로 아래의 코드라고 보면 됩니다.
## app/controllers/posts_controller.rb
class PostController < ApplicationController
def index
@posts = Post.all
redirect_to "/"
end
end
참고 redirect_to 코드는 페이지 방문 시 이동을 시킬 때 쓰이는 코드입니다.
위 코드 결과는 아무리 view에 뭘 꾸몄어도, /posts/index 페이지에 방문 시 결국 Controller을 먼저 방문을 하게되고, redirect_to 코드로 인해 메인페이지로 이동시킵니다.
루비온 레일즈 Ruby on Rails ROR
'프로그래밍 공부 > Ruby on Rails : 이론' 카테고리의 다른 글
Ruby on Rails : Console 활용하기 (2) | 2019.11.01 |
---|---|
Ruby on Rails : MVC 마스터를 위한 노가다 CRUD(게시판 제작) (0) | 2019.11.01 |
Ruby on Rails : V (View) (0) | 2019.10.31 |
Ruby on Rails : M (Model) (3) | 2019.10.31 |
Ruby on Rails : 랜덤 로또 홈페이지 제작 (VC 활용) (0) | 2019.10.31 |