복붙노트

[RUBY-ON-RAILS] 레일 4.1에서 선택에서 열거 저장

RUBY-ON-RAILS

레일 4.1에서 선택에서 열거 저장

나는 와인의 색상을 추적하기 위해 레일 4.1에서 열거 형을 사용하고 있습니다.

그리고 An.rb

class Wine < ActiveRecord::Base
    enum color: [:red, :white, :sparkling]
end

사용자가 특정 색상으로 와인을 선택할 수 있도록 내보기에, 나는 선택 생성

f.input :color, :as => :select, :collection => Wine.colors

이것은 다음과 같은 HTML을 생성합니다 :

<select id="wine_color" name="wine[color]">
  <option value=""></option>
  <option value="0">red</option>
  <option value="1">white</option>
  <option value="2">sparkling</option>
</select>

그러나 양식을 제출하기에, 나는 '1'은 (는) 유효한 색깔 아니다라는 인수 오류가 발생합니다. 나는 색상이 "1"(1)과 동일하지해야하기 때문에 이것이 실현.

정수가 아닌 문자열로 색상을 해석하는 레일을 강제 할 수있는 방법이 있습니까?

해결법

  1. ==============================

    1.좋아, 그래서 분명히, 당신은 열거의 정수 값을 저장하는 보내지한다. 당신은 열거의 텍스트 값을 보내야합니다.

    좋아, 그래서 분명히, 당신은 열거의 정수 값을 저장하는 보내지한다. 당신은 열거의 텍스트 값을 보내야합니다.

    나는 다음으로 입력을 변경 :

    f.input : 색상, : =>과 같이 선택 : 컬렉션 => Wine.colors.keys.to_a

    어느 다음 HTML을 생성 :

    <select id="wine_color" name="wine[color]">
      <option value=""></option>
      <option value="red">red</option>
      <option value="white">white</option>
      <option value="sparkling">sparkling</option>
    </select>
    

    값은 "빨간색"에 "0"에서 가서 지금 우리는 모든 설정이야.

    정기적 팔자를 사용하는 경우 '레일은 그것의 text_field :

    f.select : 색상, Wine.colors.keys.to_a

    당신이 깨끗한 사람이 읽을 수있는 특성을 가지고 싶다면 당신은 할 수 있습니다 :

    f.select : 색상, Wine.colors.keys.map {| w | [w.humanize, w]}

  2. ==============================

    2.to_a와 배열에 열거 해시를 변환 할 필요가 없습니다. 이 충분할 :

    to_a와 배열에 열거 해시를 변환 할 필요가 없습니다. 이 충분할 :

    f.select :color, Wine.colors.map { |key, value| [key.humanize, key] }
    
  3. ==============================

    3.난 그냥 내가 당신의 열거 선택에 대한 더 많은 사용자 정의 열거 라벨 및 로케일을 필요로 도움 사람들에게 공유하고자합니다 것을 함께 EnumHelper을 넣어.

    난 그냥 내가 당신의 열거 선택에 대한 더 많은 사용자 정의 열거 라벨 및 로케일을 필요로 도움 사람들에게 공유하고자합니다 것을 함께 EnumHelper을 넣어.

    module EnumHelper
    
      def options_for_enum(object, enum)
        options = enums_to_translated_options_array(object.class.name, enum.to_s)
        options_for_select(options, object.send(enum))
      end
    
      def enums_to_translated_options_array(klass, enum)
        klass.classify.safe_constantize.send(enum.pluralize).map {
            |key, value| [I18n.t("activerecord.enums.#{klass.underscore}.#{enum}.#{key}"), key]
        }
      end
    
    end
    

    로케일의 경우 :

     en:
       activerecord:
         enums:
          wine:
            color:
              red:   "Red Wine"
              white:  "White Wine"
    

    귀하의 의견에 :

     <%= f.select(:color, options_for_enum(@wine, :color)) %>
    
  4. ==============================

    4.허용되는 솔루션은 사람이 읽을 수있는 나를 위해 일을하지 않았다, 그러나 나는 이런 일에 그것을 얻을 수 있었다 :

    허용되는 솔루션은 사람이 읽을 수있는 나를 위해 일을하지 않았다, 그러나 나는 이런 일에 그것을 얻을 수 있었다 :

    <%= f.select(:color, Wine.colors.keys.map {|key| [key.humanize, key]}) %>
    

    이것은 깨끗한했지만, 난 정말 내 키를 인간화하는 데 필요한 :

    <%= f.select(:color, Wine.colors.keys) %>
    
  5. ==============================

    5.당신이 레일 4에 열거를 사용하는 경우 다음 단지 Model.enums 전화 :

    당신이 레일 4에 열거를 사용하는 경우 다음 단지 Model.enums 전화 :

    f.select :color, Wine.colors.keys
    

    HTML을 만들려면 :

    <select name="f[color]" id="f_color">
        <option value="red">red</option>
        <option value="white">white</option>
        <option value="sparkling"> sparkling </option>
    </select>
    

    또는 컨트롤러에 메소드를 추가 :

    def update_or_create
        change_enum_to_i
        ....
    end
    
    def change_enum_to_i
        params[:f]["color"] = params[:f]["color"].to_i
    end
    
  6. ==============================

    6.여기 나, 레일 4+ 위해 일한 것입니다 :

    여기 나, 레일 4+ 위해 일한 것입니다 :

    class Contract < ApplicationRecord
    
    enum status: { active:  "active", 
                   ended: "active", 
                   on_hold: "on_hold", 
                   terminated:  "terminated", 
                   under_review:  "under_review" , 
                   unknown: "unknown" 
                  }
    
    
    end
    

    내 _form.html.erb에, 나는이있다 :

      <div class="field">
        <%= form.select :status, Contract.statuses.keys, {}%>
      </div>
    

    기록을 추가 한 후 콘솔에서 테스트 :

    2.3.0 :001 > Contract.last.status
      Contract Load (0.2ms)  SELECT  "contracts".* FROM "contracts" ORDER BY "contracts"."id" DESC LIMIT ?  [["LIMIT", 1]]
     => "active"
    
  7. ==============================

    7.당신은 당신이 사용할 수있는 열거 키를 기반으로 국제화를 처리해야하는 경우 :

    당신은 당신이 사용할 수있는 열거 키를 기반으로 국제화를 처리해야하는 경우 :

    <%= f.select :color, Wine.colors.keys.map {|key| [t("wine.#{key}"), key]} %>
    

    그리고 번역 당신은 색상을 설정할 수 있습니다 :

    wine:
     red: Red
     white: White
    
  8. ==============================

    8.(? simpleform와) 여기 내 솔루션 (내 역할 "sales_rep"처럼에 밑줄을), 그리고 내가 일에 빈 옵션을 얻기 위해 필요한 방법이 있었다 몇 가지 이유입니다 :

    (? simpleform와) 여기 내 솔루션 (내 역할 "sales_rep"처럼에 밑줄을), 그리고 내가 일에 빈 옵션을 얻기 위해 필요한 방법이 있었다 몇 가지 이유입니다 :

    ApplicationHelper에서 :

    def enum_collection_for_select(attribute, include_blank = true)
      x = attribute.map { |r| [r[0].titleize, r[0]] }
      x.insert(0,['', '']) if include_blank == true
      x
    end
    

    그럼 내 형태 :

    <%= f.input :role, collection: enum_collection_for_select(User.roles), selected: @user.role %>
    
  9. from https://stackoverflow.com/questions/23686265/saving-enum-from-select-in-rails-4-1 by cc-by-sa and MIT license