[ruby-on-rails] Rails 4.1의 select에서 열거 형 저장

와인의 색상을 추적하기 위해 Rails 4.1의 열거 형을 사용하고 있습니다.

Wine.rb

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

내 뷰에서는 사용자가 특정 색상의 와인을 선택할 수 있도록 select를 생성합니다.

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' is not a valid color됩니다. 나는 때문에이 실현 color동일해야 1하지 "1".

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



답변

좋아, 분명히 저장할 열거 형의 정수 값을 보내지 말아야합니다. 열거 형의 텍스트 값을 보내야합니다.

입력을 다음과 같이 변경했습니다.

f.input :color, :as => :select, :collection => 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”에서 “red”로 변경되었으며 이제 모든 설정이 완료되었습니다.


일반 ol ‘rails text_field를 사용하는 경우 다음과 같습니다.

f.select :color, Wine.colors.keys.to_a


사람이 읽을 수있는 깨끗한 속성을 원한다면 다음을 수행 할 수도 있습니다.

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


답변

열거 형 해시를 to_a. 이것으로 충분합니다.

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


답변

열거 형 선택에 대해 더 많은 사용자 지정 열거 형 레이블 및 로캘이 필요한 사람들을 돕기 위해 공유 할 것으로 생각되는 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)) %>


답변

허용되는 솔루션은 사람이 읽을 수 있도록 나를 위해 작동하지 않았지만 다음과 같이 작동하도록 만들 수 있습니다.

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

이것은 가장 깨끗했지만 키를 인간화해야했습니다.

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


답변

Rails 4에서 enum을 사용하는 경우 다음을 호출하십시오 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


답변

나를 위해 일한 것은 Rails 4+입니다.

class Contract < ApplicationRecord

enum status: { active:  "active",
               ended: "active",
               on_hold: "on_hold",
               terminated:  "terminated",
               under_review:  "under_review" ,
               unknown: "unknown"
              }


end

my _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"


답변

열거 형 키를 기반으로 i18n을 처리해야하는 경우 다음을 사용할 수 있습니다.

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

변환에서 색상을 설정할 수 있습니다.

wine:
 red: Red
 white: White