Listigeblaj datumeroj en ActiveRecord
Foje oni volas limigi la eblajn valorojn por datumero en ActiveRecord. Unu ebleco estas krei liston de la simboloj kaj tiam krei datumkontrolilon. Ekzemple:
class Konkursanto
  konkursaj_tipoj = [:komencanto, :progresanto]
  validates :konkurstipo, inclusion: { in: konkursaj_tipoj }
end
class KreiKonkursantoj < ActiveRecord::Migration
  def change
    create_table :konkursantos do |tablo|
      tablo.string :konkurstipo, default: "komencanto"
    end
  end
end
kaj en la datumbazo vi aldonas la konkurstipo kiel ĉeno.
Rails 4.1 kaj poste
Versioj de Rails >= 4.1 enhavas novan klasfunkcion nomitan: enum. La supra ekzemplo uzanta ĉi tion estas:
class Konkursanto
  enum konkurstipo: %i(komencanto progresanto)
end
class KreiKonkursantoj < ActiveRecord::Migration
  def change
    create_table :konkursantos do |tablo|
      tablo.integer :konkurstipo, default: 0
    end
  end
end
Averto la datumbazo por ĉi tio bezonas esti entjero anstantaŭ ĉeno.
Nun vi povas atribui la datumero la rekte jene:
zam = Konkursanto.new
zam.konkurstipo = "komencanto"
ActiveRecord ankaŭ donas kelkajn helpemajn funkcojn:
- Por legi
 
zam.konkurstipo #=> komencanto
- Por atribuigi
 
zam.konkurstipo = "progresanto"
zam.konkurstipo = 0
zam.progresanto!
zam.konkurstipo = nil
- Por demandi
 
zam.komencanto?
zam.progresanto?
zam.status.nil?
- Por trovi
 
Konkursanto.komencanto
Kio okozas aŭtomate estas ke ActiveRecord tradukos la eblajn valorojn al entjeroj kaj konservas tiujn je la datumbazo. Por vidi ĉi tion vi povas demandi ActiveRecord
Konkursanto.konkurstipos
#=> {"komencanto"=>0, "progresanto"=>1}
Averto ni bezonas entajpi konkurstipos anstantaŭ konkurstipoj ĉar ActiveRecord antaŭsupozas ke la angla estas uzata.
Kiel vi vidas la tradukon al nombroj okazas laŭorde. Do vi ne povas ŝanĝi la ordon krom se vi ankaŭ ŝanĝas ĉiun valoron en la datumbazo. Vi ja povas aldoni al la fino, ĉar la nova nombro ne estos jam uzita aŭ vi povas doni malimplice la nombrojn:
class Konkursanto
  enum konkurstipo: {progresanto: 1, komencanto: 0}
end