본문 바로가기
Ruby on Rails

📚 [Ruby on Rails] 회원정보 수정 구현 ( f. 다음 주소 API )

by Nyanggu 2023. 4. 6.

버전 정보

ruby "3.1.3"
gem "rails", "~> 7.0.3", ">= 7.0.3.1"

 

구현내용

 - 닉네임, 전화번호, 주소 변경 저장

 - 닉네임 중복체크

 - 닉네임 30일 변경제한

 

 

view code

 

<%= form_tag(mypage_edit_path, method: :post, id: 'edit-form') do %>
      <%= label_tag 'nickname-input', '닉네임' %>
      <span> (최대 6자리까지 입력 가능합니다.)</span>
      <%= text_field_tag 'user[nickname]', current_user.nickname, id: 'nickname-input', :maxlength => 6 %>

      <%= label_tag 'phone-input', '전화번호' %>
      <span> (예시 : 01012345678)</span>
      <%= text_field_tag 'user[phone]', current_user.phone, id: 'phone-input', :maxlength => 11 %>

      <%= label_tag 'sample6_postcode', '주소' %>
      <%= text_field_tag 'user[postcode]', current_user.postcode, id: 'sample6_postcode' %>
      <%= button_tag '우편번호 찾기', type: 'button', onclick: 'sample6_execDaumPostcode()' %>
      <%= text_field_tag 'user[address]', current_user.address, id: 'sample6_address' %>
      <%= text_field_tag 'user[detail_address]', current_user.detail_address, id: 'sample6_detailAddress' %>
      <%= text_field_tag 'user[extra_address]', current_user.extra_address, id: 'sample6_extraAddress' %>
      <%= hidden_field_tag 'user[id]', current_user.id, id: 'id-input' %>

      <button type="submit">저장</button>
  <% end %>

 

js code

<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script> <!-- 주소 api -->
<script>
  //주소 api
  function sample6_execDaumPostcode() {
      new daum.Postcode({
          oncomplete: function(data) {
              // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

              // 각 주소의 노출 규칙에 따라 주소를 조합한다.
              // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
              var addr = ''; // 주소 변수
              var extraAddr = ''; // 참고항목 변수

              //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
              if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                  addr = data.roadAddress;
              } else { // 사용자가 지번 주소를 선택했을 경우(J)
                  addr = data.jibunAddress;
              }

              // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
              if(data.userSelectedType === 'R'){
                  // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                  // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                  if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                      extraAddr += data.bname;
                  }
                  // 건물명이 있고, 공동주택일 경우 추가한다.
                  if(data.buildingName !== '' && data.apartment === 'Y'){
                      extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                  }
                  // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                  if(extraAddr !== ''){
                      extraAddr = ' (' + extraAddr + ')';
                  }
                  // 조합된 참고항목을 해당 필드에 넣는다.
                  document.getElementById("sample6_extraAddress").value = extraAddr;
              
              } else {
                  document.getElementById("sample6_extraAddress").value = '';
              }

              // 우편번호와 주소 정보를 해당 필드에 넣는다.
              document.getElementById('sample6_postcode').value = data.zonecode;
              document.getElementById("sample6_address").value = addr;
              // 커서를 상세주소 필드로 이동한다.
              document.getElementById("sample6_detailAddress").focus();
          }
      }).open();
  }
  $(document).ready(function() {
    // Ajax 요청 성공 후 실행될 콜백 함수
    function successCallback(data) {
      // 변경된 정보를 받아옴
      var nickname = data.nickname;
      var phone = data.phone;
      var postcode = data.postcode;
      var address = data.address;
      var detailAddress = data.detail_address;
      var extraAddress = data.extra_address;

      // 뷰 업데이트
      $('#nickname-input').val(nickname);
      $('#phone-input').val(phone);
      $('#sample6_postcode').val(postcode);
      $('#sample6_address').val(address);
      $('#sample6_detailAddress').val(detailAddress);
      $('#sample6_extraAddress').val(extraAddress);
    }

    // 저장 버튼 클릭 시 이벤트 처리
    $('form').on('submit', function(e) {
      e.preventDefault();
      const newNickname = $('#nickname-input').val();

      // Ajax 요청
      $.ajax({
        url: $(this).attr('action'),
        type: $(this).attr('method'),
        data: $(this).serialize(),
        success: successCallback,
        complete: function() {
          // 페이지 새로고침
          location.reload();
        }
      });
    });
  });
</script>

 

controller code

class MypageController < ApplicationController

    def index
    end

    def edit
        user = User.find(params[:user][:id])
        nickname = params[:user][:nickname]
      
        if user
          if user.nickname != nickname && KakaoUser.where.not(id: user.id).where(nickname: nickname).exists?
            render js: "alert('이미 사용중인 닉네임입니다. 다른 닉네임을 입력해주세요.');"
          else
            user_info_history = UserInfoHistory.new(user_id: user.id)
            change_params = {}
      
            if user.nickname != nickname
                # 닉네임 변경 30일 제한
                user_info_history_day = UserInfoHistory.where(user_id: user.id, change_type: '닉네임').order(created_at: :desc).first
                
                if user_info_history_day.nil? || user_info_history_day.created_at < 30.days.ago
                    change_params[:change_type] = '닉네임'
                    change_params[:change_before] = user.nickname
                    change_params[:change_after] = nickname
                    user.nickname = nickname
                else
                    render js: "alert('닉네임은 30일에 한번만 변경 가능합니다.');"
                    return
                end
            end
      
            if user.update(edit_params)
              if change_params.present?
                user_info_history.update(change_params)
              end
              render js: "alert('저장되었습니다.');"
            end
          end
        end
      end
      

    private

    def edit_params
        params.require(:user).permit(:phone, :postcode, :address, :detail_address, :extra_address, :id, :nickname)
    end
end

댓글