ruby on rails 에서 devise를 다뤄서 유저의 타입 나누는 방법을 어떻게 해야할까요?

조회수 1250회

안녕하세요! 제가 어떤 프로그램을 참여하면서 ruby on rails를 처음으로 접해보게 되었습니다.

거기서 로그인 관련 기능은 devise 라는 gem(아마도 라이브러리..?)을 사용해서 하는 것이 좋다고 하는데 몇가지 기능들을 보니 devise를 사용하는 것이 확실히 편하다고 생각되게 되네요 ㅎ

그런데 여기서 궁금한 점이 있는데 만약 유저의 타입을 나눠줘야 할 때는 어떻게 할 수 있나요?

예를 들어서 특정 서비스가 있는데 그 서비스를 사용하는 사람들은 선생님들과 학생들이라고 해보겠습니다.

그렇다면 선생님들은 학생들이 가지고 있지 않는 필드 (예를 들어 담당 과목 등)가 있을 것이고 학생들 또한 선생님들이 가지고 있지 않는 필드(학년, 반, 번호, 등수 등)를 가지고 있을 수 있습니다.

이것을 하나의 user 모델에 다 넣기에는 사용자가 선생님 일 때는 빈 필드 값들이 많을 것이고, 반대의 경우도 마찬가지일 것입니다.

devise를 이용해서 유저의 타입을 나누는 것은 어떻게 해야하나요?? devise를 두개를 만들면 데이터베이스도 두개가 생기는 것이니 그에 따른 아이디 중복 검사라던지 그러한 작업을 또해줘야하니 복잡할 것으로 생각되네요.

http://stackoverflow.com/questions/9472852/devise-and-multiple-user-models 구글링 결과 이방법을 찾기는 했는데... 이해가 잘되지 않아서.... 혹시 이 방법을 이해하신분이 계시다면 이 방법에 대해서 설명해주셔도 감사합니다 ㅠ

제가 생각해본 방법도 있긴 합니다. 이미지 그림에서 처럼 devise로 user를 만들고 bash 창에 rails g model 을 통해서 teacher와 student 모델을 각각 만들어 줍니다 그리고 그 안에 필드로 user_id를 넣어서 관계형? 데이터 베이스를 형성해 주는 것이죠(1:1관계 이겠지만...?) 이렇게 하면 devise의 기능 (현재 로그인이 되어 있는지, 로그인 되어있는 사람의 이메일 등)을 사용할 수 있을 것이고, type 체크를 통하셔 각각에 타입에 맞는 모델들을 접근 할수 있을 것이고 거기서 다른 데이터를 꺼내오는 방식을 생각해 보았습니다. 이렇게 해도 될까요?

  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 제 생각으로도 문제 없어 보입니다. 유연수 2016.7.14 05:18

1 답변

  • 위의 스택오버플로우 링크에서 설명하는 첫번째 방법이 제안하신 방법이니 다른 두번째 방법만 설명하겠습니다.

    Single table inheritance라는 방법을 이용해서 하나의 테이블에 대응하는 두개의 모델을 이용하는 방법입니다. 방법은 다음과 같습니다.

    (1) 모든 필드를 가지고 있는 테이블을 만듭니다.

    # db/migrate/00000000_create_users.rb
    class CreateUsers < ActiveRecord::Migration
      def change
        create_table :users do |t|
            t.string :type #Sti를 이용하기 위해서는 Type필드가 핵심입니다.
            t.string :name
            t.string :major
            t.string :class_number
            t.integer :year
            t.timestamps null: false
        end
      end
    end
    

    (2) User모델을 상속받는 Student와 Teacher모델을 만듭니다.

    #models/teacher.rb
    class Teacher < User
    
    end
    
    #models/student.rb
    class Teacher < User
    
    end
    

    (3) 이렇게 하고 나면 Teacher를 Teacher.create(name: "선생님", major:"수학")와 같은 명령으로 만들수 있습니다. 이 때 로그를 보면 아래와 같은데요.

       (0.1ms)  begin transaction
      SQL (0.8ms)  INSERT INTO "users" ("type", "name", "major", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["type", "Teacher"], ["name", "선생님"], ["major", "수학"], ["created_at", "2016-07-16 04:35:47.921290"], ["updated_at", "2016-07-16 04:35:47.921290"]]
       (1.5ms)  commit transaction
    => #<Teacher id: 1, type: "Teacher", name: "선생님", major: "수학", class_number: nil, year: nil, created_at: "2016-07-16 04:35:47", updated_at: "2016-07-16 04:35:47">
    

    생성된 Teacher레코드의 type에 자동으로 "Teacher"라는 값이 들어가 있는걸 볼 수 있습니다. 레일즈가 Teacher 모델의 레코드를 만들면 자동으로 User테이블에 type을 Teacher로 해서 저장하는겁니다.


    • 장점

      • 하나의 사용자 모델로 학생과, 선생님을 모두 읽어들일 수 있다(예를들어 User.all하면 Student와 Teacher를 모두 불러올 수 있다)
      • 하나의 테이블을 사용하지만 다른 모델이므로, 서로 다른 메소드를 구현할 수 있다.
    • 단점

      • 사용하지 않는 빈 필드가 있게 된다.(Student모델의 경우 Major)

    따라서 대부분의 칼럼이 일치하고, 몇개만 서로 다른경우에 사용하면 좋습니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)