꼬마선원의 개발일지 2주차

By ccoma | August 21, 2018


첫 일지 작성 이후 1주일 후, 새벽 1시 30분, 사무실.

이번주에는 지난주에 구현 한 내용이랑 크게 달라지는 점이 없어서 그나마 덜 삽질했다.
그렇다고 안했다는건 아니고…


제일 많이 고민했던 점은, MVC 모델에 대한 고민이었다.


지난주 개발일지에 적었듯, Laravel에서는 migration, model, controller을 한번에 만들 수 있다. (물론 view도 함께 만들 수 있…을…텐데 내가 옵션 명령어를 모르겠다.) 그런데 이렇게 한번에 만들었더니 내가 혼란이 오기 시작했다.


MVCModel, View, Controller인데, 데이터베이스를 위한 migration 파일을 한번에 만들다보니, Migration, View, Controller로 자꾸 착각을 했다. 그래서 A 모델에서도 a 테이블에 접근해야 하고, B 모델에서도 a 테이블에 접근해야 하는 경우, 어... 이래도 되나...? 이러면서 잠시잠깐 고민을 했는데 이 시간이 나중에 지나고 보니 꽤 되었던 것 같다.


학교 다닐때는 MVC 모델로 구현하는게 어렵지 않았던 것 같은데, 하다보니 생각보다 매우매우매우매우 헷갈린다.

삐그덕 거리는게 불안하긴 한데, 일단은 완성하고 보수공사를 해야할 것 같다. ㅎㅎ




개발하며 끄적이는 의식의 흐름

지난주에 한 삽질이 크게 도움이 되어 Admin PageChallenge Page를 구현하는데는 큰 어려움이 없었다.
그래서 아래처럼 데이터베이스에 있는 값을 뽑아서 추출하도록 만들 수 있었다.




그럼에도 몇 가지 내 시간을 퍼먹은 기능이 몇 가지 있었다.

도대체 왜!! 인지 모르겠는데 계정을 ccoma, bpsec 두개를 만들고 로그인을 하면 LoginController에서는 각 계정으로 정보가 제대로 나온다. 근데 페이지만 넘어가면 무조건 ccoma가 나온다.


Laravel에서는 attempt를 이용해서 로그인을 하면 바로 Auth::user()를 사용해서 데이터베이스에 저장되어 있는 사용자 정보를 확인할 수 있다.


물론 User.php에서 아래와 같이 필터링을 해서 특정 부분은 숨길 수 있다.

protected $hidden = [
    'password', 'remember_token', 'reg_date', 'idx',
];


그런데 한가지 더 이상한 점이 Auth::user()를 사용 해 사용자 정보를 확인하면 id가 무조건 다 0이 나왔다. 며칠 동안 왜 도대체 페이지만 넘어가면 왜!!! ccoma로 다시 바뀌는 것인가 id는 왜 멀쩡한 ccoma를 두고 0이 나오는가를 두고 엄청 고민했었다. 인터넷을 아무리 뒤져도 Laravel을 사용하는 사람들은 다 attempt를 사용 해 로그인을 구현했는데, 왜 나는 안되는지 원인을 못찾았다.


그래서 내가 로그인을 새로 짜야 하는 것인가...를 두고 심각하게 고민을 했었다.
새로 구현해도 로그인 기능이 크게 어렵진 않지만 괜히 이상하게 세션 관리를 어떻게 해야하는 것인가에 대해 고민이 되기도 했고…


남들 다하는거 나는 못하는것인가 이런 묘한 패배감(?)이 들어서 계속 찾아봤다.
사실 로그인 한줄로 할 수 있는거 늘리고 싶지 않았던 것도 있고 ㅎㅎ


원인은!!

Laravel에서는 로그인을 할 때, users라는 테이블을 만들 때, id 컬럼은 auto_increment로 간주한다고 한다. 근데 나같은 경우는 auto_incrementidx로 두고, 이 idx를 기본키로 두고 사용했다. id 컬럼은 정말 사용자가 접속하기 위한 id로 사용하고 있었는데, Laravel에서는 이를 인덱싱 요소로 생각 해 발생 한 문제점이었다.


그래서 User.phppublic $incrementing = false; 이 단 한줄을 추가 해 해결할 수 있었다. 내 시간 돌려달라


두 번째는 Model에서 구현한 함수를 어떻게 Controller에서 호출 할 것인가에 대한 고민이었다.

Laravel에서는 친절하게도 Model을 만들기만 하면 기본적인 DB 접근은 할 수 있도록 되어있다. 그러니까 select * from table 쯤은 model명::all()로 뽑아낼 수 있다. 아 물론, 지난번에 말했듯이 네이밍을 정확하게 해 주어야 한다.

만약 UserController.php가 Controller라면, Model은 User.php, 테이블 명은 users여야 한다.

쨌든 기본적은 접근은 아래와 같이 할 수 있다.

// MainController.php

use App\Course;
use App\Challenge;
use App\Main;

class MainController extends Controller
{
	public function index() {
		$courses = Course::all();
		$phases = Challenge::all();
		return view('main', compact('courses', 'phases'));
	}
}


한번 씩 내가 필요한 몇 개의 값만 필요할 때가 있는데, 이건 Model에 내가 따로 함수를 구현해야 했다.
그런데 아무리 Model에서 함수를 구현해도 호출이 안됬다.


알고보니 Model에서 구현한 함수를 Controller에서 호출하려면 public static funtion a()처럼 static을 붙여 주어야 했다. 그리고 아래처럼 Controller에서는 Model명::함수명의 형태로 호출하면 된다.

# MypageController.php  

public function changeNickname(Request $request) {
	...

	$result = Mypage::change_nickname($request->nickname, Auth::user()->id);

	...
}
# Mypage.php  

public static function change_nickname($nickname, $user) {
	
	# change_nickname
}


저것도 생각보다 오래 고민했던 것 같은데 단어 한개 붙여주니까 잘ㅋ됨ㅋ




그 다음은 CSS였다.

디자이너가 HTML/CSS까지는 작업을 해서 주었는데, 이상하게 내가 작업을 해서 원하는 값을 출력하면 CSS가 깨지는 것이다. 바로 밑에 나타나야 할 아이가 저~~~ 밑으로 가서 안보여… 어디갔니..

그래서 개발자 도구를 사용해서 디자이너가 짜 준 소스코드와 내가 짠 소스코드를 한줄한줄 비교했다.

짤 때는 몰랐는데 왜이렇게 김…


거기다 내가 짠건 데이터베이스의 값을 뽑아 와서 반복문을 돌면서 요소 하나하나를 만들어서 소스코드가 엄청 길어져 있어 더 비교하기가 눈아팠다. 비교하다보니 <head> 태그 안에 들어가야 할 내용이 내가 짠 소스코드에는 <body> 안에 있는 <header>라는 태그 안에 들어가 있었다. <header>는 사용자의 닉네임과 페이지를 이동하기 위한 단축키를 두는 곳인데, 왜 뜬금없이 여기에서 stylesheet를 가져오는지..


역시 내잘못이었다.

View를 구현할 때 공통되는 부분을 계속해서 불러오기 귀찮아서 master layout을 구현하고 여기에서 head, header, content, footer 레이아웃을 따로 만들어 각각을 필요 시마다 불러 와 사용했다.


그런데 이 때 content 영역에서 header를 호출 할 때 내가 순서를 잘못 해뒀다.

아래처럼 했어야 제대로 들어갔을텐데, 나는 includes.headermaster.blade.php에서 content라는 섹션 전에 넣어 뒀었던 것이다.

# *.blade.php

@extends('master')
@section('content')
@include('includes.header')


역시 컴퓨터는 잘못이 없다.
뭔가 인정하긴 싫지만 안되면 그건 다 내탓이더라.


쨌든 CSS가 깨지는건 개발자 도구로 하나하나 비교해가며 어찌어찌 해결 할 수 있었다.




아 그러다보니 생각났는데, Laravel에서는 입력 값을 검증할 수 있는 방법이 손쉽게 되어있다.

만약 idpw를 입력받는다고 했을 때, 이 값들이 제대로 입력되었는지 확인하기 위해 일반 php 코드에서는 isset()를 사용 해 검사해야 한다. 그런데 isset()는 말 그대로 값이 있는지 없는지만 검사할 뿐, 길이 제한 같이 또 다른 조건이 있다면 이를 새로 구현해 사용해야 한다.

이 때 사용하는게 Validation이라는 것이다.


GET이나 POST로 값을 넘기면, 그 요청을 처리하는 함수에서는 Request $request 형태로 요청을 받을 수 있다. 이 때, $변수명->validate를 사용하면, 입력 값이 제대로 들어왔는지, 최소 길이나 최대 길이는 충족하는지, 패스워드의 경우 패스워드 입력 칸과 패스워드 확인 칸에 입력된 값이 같은지까지 확인할 수 있다.

public function index(Request $request) {
	$request->validate([
			'id' => 'required',
			'password' => 'required',
		]);
}


아 물론, 패스워드 입력 칸과 패스워드 확인 칸에 입력된 값이 같은지 확인하기 위해서는 input 태그의 name을 규칙에 맞게 설정 해 주어야 한다. 예를 들어, 패스워드 입력 칸의 name이 password라면, 확인 칸의 name은 password_confirmation이어야 한다.

굿굿




마지막 삽질은 아직 발목이 잡혀있는 기능인데, password 변경하기Mypage에서 학습 진행도 확인하기 이다. password 변경하기는 로그인처럼 Laravel에서 구현되어 있는 함수가 있는걸로 아는데 아직 못찾았다.

금방 찾을 것 같으니 아마 오늘 내로는 되지 않을까 싶다.


문제는 학습 진행도 확인하기인데, 어제까지만 해도 뭘… 어떻게 쿼리를 짜야하나 하다가 어제 자려고 누웠다가 갑자기 유레카! 하고 떠올랐다.

역시 안되면 걍 던져야 함(?)


뭔가 두 테이블을 잘 join해서 이렇게저렇게 쓱싹 하면 따란~ 하고 될 것 같은데 오늘 출근하자마자 Laravel 쿼리에서 join을 찾아보니 inner join, left join 기타 등등.. 뭔 join이 이렇게 많은지 학교 다니면서 받은 성적 중에 몇 없는 A 중에 하나가 데이터베이스고, SQLD 자격증도 있는데 join의 기능은 알지만 inner join이 뭐였는지, left join이 뭐였는지 기억이 안난다.


3학년 때 데이터베이스 수업을 들었으니 어언 2년 전인데 까먹을만 하지 싶다.
하긴 올해 딴 정보처리기사 실기 시험에서도 데이터베이스 과목은 0점이더라. (눙물..)


구글링을 좀 하면 다시 내 기억 저편 어딘가에 있는 지식이 하고 올라오길 바라며 아마 이 부분도 오늘 중으로는 구현 되지 않을까 싶다.


아 오늘 회의 있구나.


정정해야겠다.

오늘 중으로는 이번주 중으로는 구현 되지 않을까 싶다.




삽질일기 2주차의 끝

지난 주말에 간만에 본가에 간 김에 부모님이랑 피서 차(?) 모 지역에 있는 백화점에 다녀왔다.


여기가 특이한게 L 백화점, L 마트, L 시네마 등 L 사의 모든 문화 공간이 모인 L 몰과 A 백화점, C 영화관 등 A 사의 문화 공간이 있는 A 몰이 근방에 있다는 점이다. 거기다 A 몰은 지하철 역(기차역)을 가운데 두고 있는데, 역사에서 L 몰로 통하는 길까지 만들어 두었다. (이하 쇼핑몰)


처음엔 이 두 쇼핑몰이 어떻게 공존할 것인가를 두고 가격경쟁을 해서 손님을 끌어모으지 않을까! 라고 생각했었다. 실제로 초반에는 할인률이 서로 살짝 달라서 두 쇼핑몰을 왔다갔다하며 더 저렴한 곳에서 구매했었다.


아니면 둘 중 하나가 망하던가!


하지만 완전히 자리잡힌 지금, 두 쇼핑몰이 완벽히 공존하고 있으며, 양쪽 다 사람이 바글바글 하다.

그러다보니 판매하는 물건, 컨텐츠가 90% 이상 동일한데, 어떻게 같은 공간에 있을 수 있는 것인가 생각하게 되었다.


돌아다니면서 살펴보니, 양 쪽 매장에 있는 고객층이 달랐다.


L 몰은 주로 어린 아이가 있는 가족을 타겟으로 잡은 것 같다. 그래서 각 층의 중간에 어린아이들을 위한 놀이공간이 있고 중간에 쉴 수 있는 의자도 많은 편이다.

반면 A 몰젊은 사람들을 타겟으로 잡았지 싶다. 그래서 쇼핑몰은 2~30대 여성을 겨냥한 곳이 많고 팬시샵, 1000원 샵 등 젊은 세대가 좋아하고 한번 쯤 들려보는 매장과 서가X쿡 같은 식당들이 입점 해 있다.


살펴보면 판매하는 상품이나 컨텐츠에 대해서는 양 쪽 쇼핑몰에 차이가 없다.

그런데 타겟팅을 서로 다른 방향으로 했으며, 타겟팅 한 고객층에 따라 마케팅이나 매장 디자인, 입점 매장을 살짝 다르게 해 서로 공존할 수 있게 되었다. 진짜 두 쇼핑몰이 그렇게 타겟팅을 해서 전략을 그런 방향으로 세웠는지는 확인이 불가능하다. 뇌피셜임 ㅎㅎ


사실 지금 하고 있는 Hacking on Lucy 또한 비슷한 상황이라 더 눈여겨 본 것 같다.

해킹을 공부하고 싶은 사람들은 많고, 그 사람들을 위한 교육 컨텐츠는 부족하다.

때문에 많은 회사들이 이 시장에 뛰어들고 있다고 한다.

해킹계에 떠오르는 블루오션 인 셈이다.


이런 상황에서 우리가 선두주자가 되고싶긴 하지만 사실 어디서 어떤 회사가 갑자기 뿅! 하고 나타날지도 모르고, 이 사업을 준비중이라는 회사들 또한 만만치 않은 회사들이기 때문에 차별성에 대해 굉장히 많은 고민을 했었다.

결국 타겟팅부터 다시 시작 해 통과 된(?) 기획안이 현재 개발중인 Hacking on Lucy인데, 이번에 두 쇼핑몰의 타겟팅과 전략을 눈으로 보고나니 우리 한 타겟팅과 전략에 대해 다시 고민하고 생각해 보는 계기가 되었다.


아 그렇다고 기획을 날리자는 이야기는 아닙니다 이사님


앞으로 Hacking on Lucy에서 할 일은 각 코스와 단계를 구성하는 것인데, 이걸 어떻게 채워야 할지 앞으로도 계속 고민해야 할 것 같다.


개발은 언제 다한담…

comments powered by Disqus