13

列挙型の値をアクティブ レコードに格納し、アプリで表示するために「タイトル」に変換する最良の方法を見つけようとしています。

IE

レビュー列挙:

UNREVIEWED = {:title => "Unreviewed", :name => "UNREVIEWED"}
REVIEWED = {:title => "Reviewed", :name => "REVIEWED"}
FLAGGED = {:title => "Flagged as inappropriate", :name => "FLAGGED"} 

したがって、Javaランドでは、ENUM名(REVIEWED)をデータベースに保存し、その名前をサーバー上の実際の列挙型に変換して、ヘルパーメソッドを呼び出すことができました。

review = Review.valueOf(review)
review.title()

これを達成するためにレールでできる同様のことはありますか?

参考までに、私たちはアプリを非常に小さく保とうとしているので、GEM なしでこれまたは同様のことを簡単に達成できれば素晴らしいと思います。

これを行うための「標準的な」方法はありますか?私がこの問題に苦労したのは初めてではないと思いますか?

ありがとう!

4

5 に答える 5

29

フレームワークの一部であるため、ActiveRecord 列挙型が最適な方法です (バージョン 4.1 以降)。

その使用法は非常に簡単です。

移行:

class AddEnumToMyModel < ActiveRecord::Migration
  def change
    add_column :my_model, :status, :integer, default: 0
  end
end

モデル:

class MyModel < ActiveRecord::Base
  enum status: [:draft, :beta, :public]
end

次に、意志を使用します。

MyModel.draft # gets all drafts
MyModel.last.draft? # checks if the last model is draft
MyModel.last.status # gets the string description of the status of my model

モード情報については、ドキュメントを参照してください。

于 2014-01-13T07:18:09.683 に答える
6

この問題に関する投稿はたくさんありますが、これはそれらのほとんどを指していると思います: http://thinkinginrails.com/2010/04/using-enums-for-constants/

これは過度に設計されたものであり、Ruby のような動的型付け言語では必要ないと思います。

文字列を使用するだけです!

次に、次のように使用できます。

class Review < ActiveRecord::Base
  validates_inclusion_of :status, :in => ["UNREVIEWED", "REVIEWED", "FLAGGED"]
  def status
    read_attribute(:status)
  end
  def status= (value)
    write_attribute(:status, value)
  end
end
于 2013-02-16T18:57:18.970 に答える
4

@Godsaur の例を使用します。

class MyModel < ActiveRecord::Base
  enum status: [:draft, :beta, :public]
end 

文字列値は次のように取得できます。

MyModel.last.status
=> "beta"

ただし、「タイトル」が必要な場合は、次のことができます。

MyModel.last.status.titleize
=> "Beta"
于 2015-04-01T15:04:48.213 に答える
1

@Godsaurの答えが正しいことに同意しますが、個人的には、整数値を格納して意味のある文字列に相当するものを表すアプローチは好きではありません(十分なデータベースインデックスが作成されている場合、および/またはDBエンジンで文字列をクエリするコストが整数のクエリのそれ)。

私のアプローチは通常、テキスト値をデータベースに保存することです (DB レコードを理解しやすくするため)。

my_model.rb

class MyModel < ActiveRecord::Base

  STATUSES = HashWithIndifferentAccess.new({unverified: 'unverified', reviewed: 'reviewed', flagged: 'flagged'})
  #the text values are similar to their symbols key
  #you could also define additional attributes for each key if needed. Ex:
  #STATUSES = {unverified: {title: 'Unverified Text Title', txt: 'unverified'}, ...}

  # assuming a 'status' field
  scope :unverified, -> { where(status: STATUSES[:unverified]) }

  def unverified?
    status == STATUSES[:unverified]
  end

  # Or
  STATUSES.each do |sym, val|
    define_method("#{sym}?") {status == val}
  end
end

my_view.erb

<%= MyModel::STATUSES[@my_model.status] %> or 
<%= MyModel::STATUSES[@my_model.status].title %>
于 2014-09-18T01:56:33.397 に答える