[Rails]enum을 사용하여 사용자 속성 추가

35732 단어 Railsenumgemtech

enum을 이용하여 관리자, 일반적인 상황을 표시하다

enum를 사용하여 사용자 속성(일반적으로 관리자)을 관리하고 사용자 속성에 따라 로그인 후의 페이지 이동을 제어합니다

이른바 enum(열거형)


프로그램에서 처리할 수 있는 숫자 열의 별명을 지정합니다
한 열에 지정된 여러 상수를 저장할 수 있도록
이름에 수치를 분배함으로써 코드의 가독성을 높일 수 있고 불필요한 문제를 방지할 수 있다
주로 다음과 같은 특징이 있다
  • 이름(문자열) 목록에 고유 값 할당
  • 정의된 순서대로 값 분배
  • enum형의 상수는 정의를 제외한 값을 받아들이지 않는다
  • users 테이블에 role 열 추가


    다음 순서에 따라 실시하다
  • users표에서 준비한enum용 열
  • 모델에 정의enum
  • users표에 enum열을 추가하여 사용roleenum 데이터 유형 integer
  • general...일반
  • admin...관리자
  • 마이그레이션 파일 작성 및 편집
    rails g migration AddRoleToUsers
    
    class AddRoleToUsers < ActiveRecord::Migration[5.2]
      def change
        add_column :users, :role, :integer, null: false, default: 0
      end
    end
    
    rails db:migrate
    

    주안점

  • 데이터가 일반 또는 관리자여야 하므로 null: false
  • 초기 값이 일반적으로 필요하므로 default: 0
  • 모델 정의


    그리고use모델에서enum을 사용하여 여러 상수 목록을 등록합니다
    공간 간격 정의enum의 값은 나중에 추가할 때 더욱 수월합니다
    예제)
    # NG
    enum: { draft: 0, in_review: 1, published: 2, archived: 3 }
    
    # この場合、ステータスを追加する際には数字を増やしたものを定義するしかない。
    enum: { draft: 0, in_review: 1, published: 2, archived: 3, review_requested: 4, change_requested: 5 }
    
    # GOOD
    enum: { draft: 0, in_review: 10, published: 20, archived: 30 }
    
    # 間に定義することができるので、追加するenumと他の値の関係性を理解しやすい
    enum: { draft: 0, review_requested: 5, in_review: 10, change_requested: 15, published: 20, archived: 30 }
    
    1과 0으로 정의됨
    app/models/user.rb
    class User < ApplicationRecord
    
    	enum role: { general: 0, admin: 1 }
    
    	# もしくは
    	enum role: %i[general edmin]
    
    end
    
    이 값은 Role 열에 저장됩니다.
    수치에 따라 일반인지 관리자인지 구분하다

    ※ 상수 목록 획득 방법


    참고로 モデルクラス.enumカラム名の複数形에서 산열 형식으로 정의된 상수 목록을 얻을 수 있습니다
    [16] pry(main)> User.roles
    => {"general"=>0, "admin"=>1}
    
    또한 키나value만 원하면 다음과 같이 쓸 수 있습니다.
    [7] pry(main)> User.roles
    => {"general"=>0, "admin"=>1}
    [8] pry(main)> User.roles.keys
    => ["general", "admin"]
    [11] pry(main)> User.roles.values
    => [0, 1]
    

    Admin 사용자 만들기

    seed 파일을 사용하여 관리자 권한을 가진 사용자 만들기
    db/seeds.rb
    User.create!(last_name: "あどみん",
      first_name: "あどみん",
      email: "[email protected]",
      password: "admin",
      password_confirmation: "admin",
      role: 1
    )
    
    확인
    % rails c
    id: 11,
      email: "[email protected]",
      crypted_password:
       "$2a$10$4AkXbdWoZVO79blLtYzC4eL46eFEiKOdOYfSQbRnC6ISKrfjBq.9G",
      salt: "kKHyQYuyDd2XcohiVWso",
      last_name: "あどみん",
      first_name: "あどみん",
      created_at: Fri, 16 Jul 2021 16:28:55 JST +09:00,
      updated_at: Fri, 16 Jul 2021 16:28:55 JST +09:00,
      avatar: nil,
      reset_password_token: nil,
      reset_password_token_expires_at: nil,
      reset_password_email_sent_at: nil,
      access_count_to_reset_password_page: 0,
      role: "admin">]
    
    열에 저장role1하여 admin로 식별

    form_with로 엔움의 밑줄 만들기 (i18n 일본어화)


    전제 조건

    users 사용roleenum의 유형을 예로 들면
    일반 또는 관리자 허용
    db/schema.rb
    create_table "users", force: :cascade do |t|
        t.integer "role"
    end
    
    app/models/user.rb
    enum role: { general: 0, admin: 1 }
    

    드롭다운 형식의 창


    드롭다운 형식은 일반적으로 다음과 같다integer
    <%= f.select カラム名, {'選択肢': DBに保存する値}, {オプション}, {classなどの要素} %>
    

    enum을 사용하는 열에서 f.select 사용하기


    그리고 f.select의 열에 하단 형식의 창을 만듭니다
    직접 사용enumkey
    <%= f.select :role, User.roles.keys.to_a, {}, class: 'form-control' %>
    

    주안점

  • to_a는 상수 목록 획득 방법User.roles 산열 형식으로 획득 가능
    User.roles
    => {"general"=>0, "admin"=>1}
    
  • モデルクラス.enumカラム名の複数形에서 해시 키 꺼내기
  • .keys 방법은 산열을 수조로 바꾸는 방법이다

  • enum_help 가져오기

    .to_a 일본어화된 경우 쓰기 방식이 바뀝니다.
    ei18nenum_help에 정의된 값enum을 녹일 수 있는gem를 가리킨다
    또한 i18n에서는 ransack가 지원되지 않으므로 enum, 자체제작enum_help이 지정한 상수와enum의 쌍을 사용해야 한다.
    먼저 가져오기integer다음 반환값 일본어
    User.roles
    => {"general"=>0, "admin"=>1}
    
    먼저 설치
    gem 'enum_help'
    
    bundle install
    
    config/locales/activerecord/ja.yml
    ja:
      enums:
        user:
          role:
            general: '一般'
            admin: '管理者'
    

    호출 방식


    일본어 호출을 사용하려면 열 뒤에 enum_help를 추가하십시오
    그러나 모형을 호출할 때 열은 복수 형식이다
    모델 인스턴스 등을 호출할 때의 열은 단수 형식입니다.
    User.roles_i18n
    => {"general"=>"一般", "admin"=>"管理者"}
    
    @user.role_i18n
    => "管理者"
    
    위에서 말한 바와 같이value의 수치(0과 1)는 일본어로 바뀌었다

    일본어화된 enum열에서 f.select 사용하기


    아까 엔음.help를 이용하여 다시 쓰면 다음과 같다
    <%= f.select :role, User.roles_i18n.invert, {}, class: 'form-control' %>
    
    => {"一般"=>"general", "管理者"=>"admin"}
    

    주안점

  • _i18n를 통해User.roles_i18n.invert 취득 가능
  • {"一般"=>"general", "管理者"=>"admin"} 방법으로 교환invertkey따라서 다음과 같은 값 0(일반) 또는 1(관리자)이 DB에 저장됩니다.

  • invert 방법을 사용하지 않으면 다음과 같이 반환됩니다.
    <%= f.select :role, User.roles_i18n.invert, {}, class: 'form-control' %>
    
    => {"general"=>"一般", "admin"=>"管理者"}
    

    키가 이렇게 저장되기 때문에 오류가 발생했습니다

    ransack 사용 시


    아까는 밑에 있는 형식일 뿐인데, ransack에서도 검색 형식을 사용하는 방법입니다.
    Role 열을 기준으로 숙어 검색(Predicate)은eq. 즉, 검색이 완전히 일치한다는 뜻이다.
    <%= f.select :role_eq, User.roles_i18n.invert.map{|key, value| [key, User.roles[value]]}, { include_blank: t('defaults.unspecified') }, { class: 'form-control mr-1' } %>
    
    配列の入った変数.map {|変数名| 処理内容 }
    User.roles_i18n.invert.map{|key, value| ['表示させる値', '送信する値' ]}
    
    User.roles_i18n.invert.map{|key, value| [key, User.roles[value]]}
    

    주안점

  • value를 통해 문자열 해시User.roles_i18n.invert 가져오기
  • 그러나 {"一般"=>"general", "管理者"=>"admin"} 실제 DB에 저장된 것은 대응하는 인덱스이다.
  • enumransack에 맞지 않기 때문에 enum일 경우 문자열을 정수와 비교하여 오류가 발생
  • , 따라서 호출[key, value]에서 모델에 대한 정의User.roles[value]를 호출한다.
  • 맵 방법
    배열 요소를 변수에 배치하여 새 배열을 만들려면 반복 변환합니다.
    配列.map{|変数|変換処理}
    

    Enum 인스턴스 작업 방법


    예를 들어, 다음 enum이 정의되어 있다고 가정합니다.
    eunm에서 정의한 Article 상태
    app/models/article.rb
    class Article < ApplicationRecord
    
    	enum state: { draft: 0, published: 1, publish_wait: 2 }
    
    end
    
    먼저 인스턴스 생성
    [9] pry(main)> article = Article.new(state: 0)
    => #<Article:0x00007fb0853c60a8
     id: nil,
     state: "draft",
    

    인스턴스의 enum 값 확인


    [10] pry(main)> article.state
    => "draft"
    

    실례가 특정한 enum값인지 확인하기


    일종의 수확치?를 참고하십시오.
    진짜나 가짜로 답장하기 때문에if문장 등 조건부에서 사용하기 쉽다
    [12] pry(main)> article.draft?
    => true
    
    [13] pry(main)> article.published?
    => false
    

    인스턴스 업데이트


    성공의 결말!를 입력하면 지정된 값으로 업데이트됩니다.
    [13] pry(main)> article.published!
    => "published"
    

    데이터베이스에서 검색 방법


    모델 클래스enum role: { general: 0, admin: 1}のvalue(enumの数値)의 형식에 사용됩니다.
    이것은enum값으로 저장된 모든 데이터를 가져오는 방법입니다
    [2] pry(main)> Article.publish_wait
       (0.2ms)  select sql from (select * from sqlite_master where type='table' union select * from sqlite_temp_master where type='table') where tbl_name = 'articles'
      Article Load (0.2ms)  SELECT "articles".* FROM "articles" WHERE "articles"."state" = ?  [["state", 2]]
    => []
    
    [3] pry(main)> Article.published
      Article Load (0.1ms)  SELECT "articles".* FROM "articles" WHERE "articles"."state" = ?  [["state", 1]]
    => [#<Article:0x00007fdfd6c420d0
      id: 11,
      category_id: 1,
      author_id: nil,
      slug: "slug",
      title: "hhkjy",
      description: "asdf",
      body: "",
      state: "published"
    
    [4] pry(main)> Article.published.count
       (0.3ms)  SELECT COUNT(*) FROM "articles" WHERE "articles"."state" = ?  [["state", 1]]
    => 1
    

    enum 정수치의 모델 클래스를 얻습니다.enum 값


    enum에 등록된 정수 값을 얻으려면 다음과 같습니다
    enumカラム名_before_type_cast
    

    enum evaluation: { strongly_disagree: 1, disagree: 2, neutral: 3, agree: 4, strongly_agree: 5 }
    
    evaluarion = Evaluation.find_by(evaluation: 1)
    
    #=> evaluation: 'strongly_disagree'
    
    evaluation.evaluation__before_type_cast
    #=> 1
    

    좋은 웹페이지 즐겨찾기