Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ Define using implicit id values
value :name => 'Female'
end

Define using symbol ids

class Sex < ActiveEnum::Base
value :id => :m, :name => 'Male'
value :id => :f, :name => 'Female'
end

Beware that if you change the order of values defined in an enum which don't have explicit ids, then the ids will change.
This could corrupt your data if the enum values have been stored in a model record, as they will no longer map to
the original enum.
Expand Down
2 changes: 1 addition & 1 deletion lib/active_enum/acts_as_enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def to_select
end

def [](index)
if index.is_a?(Fixnum)
if index.is_a?(Integer)
v = lookup_by_id(index)
v.send(active_enum_options[:name_column]) unless v.blank?
else
Expand Down
29 changes: 19 additions & 10 deletions lib/active_enum/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ def to_select
# Access id or name value. Pass an id number to retrieve the name or
# a symbol or string to retrieve the matching id.
def get(index)
if index.is_a?(Fixnum)
if index.is_a?(Integer) || index.is_a?(Symbol)
row = store.get_by_id(index)
row[1] if row
else
value = row[1] if row
end

if (index.is_a?(String) || index.is_a?(Symbol)) && value.nil?
row = store.get_by_name(index)
row[0] if row
value = row[0] if row
end

value
end
alias_method :[], :get

Expand All @@ -71,12 +75,17 @@ def include?(value)

# Access any meta data defined for a given id or name. Returns a hash.
def meta(index)
row = if index.is_a?(Fixnum)
store.get_by_id(index)
else
store.get_by_name(index)
if index.is_a?(Integer) || index.is_a?(Symbol)
row = store.get_by_id(index)
value = row[2] if row
end
row[2] || {} if row

if (index.is_a?(String) || index.is_a?(Symbol)) && value.nil?
row = store.get_by_name(index)
value = row[2] if row
end

value || {}
end

private
Expand All @@ -87,7 +96,7 @@ def id_and_name_and_meta(hash)
name = hash.delete(:name)
meta = hash
return id, name, (meta.empty? ? nil : meta)
elsif hash.keys.first.is_a?(Fixnum)
elsif hash.keys.first.is_a?(Integer)
return *Array(hash).first
else
raise ActiveEnum::InvalidValue, "The value supplied, #{hash}, is not a valid format."
Expand Down
82 changes: 68 additions & 14 deletions spec/active_enum/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,28 @@ class NewEnum < ActiveEnum::Base; end
end

describe ".meta" do
it 'should return meta values hash for a given index value' do
it 'should return meta values hash for a given integer index value' do
enum = define_enum do
value :id => 1, :name => 'Name', :description => 'extra'
end
enum.meta(1).should == {:description => 'extra'}
end

it 'should return meta values hash for a given symbol index value' do
enum = define_enum do
value :id => :one, :name => 'Name 1', :description => 'extra'
end
enum.meta(:one).should == {:description => 'extra'}
end

it 'should match on id before name and return meta values hash' do
enum = define_enum do
value :id => :one, :name => 'Name 1', :description => 'extra'
value :id => :name_1, :name => 'Name 2', :description => 'extra2'
end
enum.meta(:name_1).should == {:description => 'extra2'}
end

it 'should return empty hash for index with no meta defined' do
enum = define_enum do
value :id => 1, :name => 'Name'
Expand Down Expand Up @@ -161,24 +176,63 @@ class NewEnum < ActiveEnum::Base; end
end

context "element reference method" do
let(:enum) {
define_enum do
value :id => 1, :name => 'Name 1'
value :id => 2, :name => 'Name 2'
context 'integer ids' do
let(:enum) {
define_enum do
value :id => 1, :name => 'Name 1'
value :id => 2, :name => 'Name 2'
end
}

it 'should return name when given an id' do
enum[1].should == 'Name 1'
end
}

it 'should return name when given an id' do
enum[1].should == 'Name 1'
end
it 'should return id when given a name' do
enum['Name 1'].should == 1
end

it 'should return id when given a name' do
enum['Name 1'].should == 1
it 'should return id when given a symbol of the name' do
enum[:Name_1].should == 1
enum[:name_1].should == 1
end
end

it 'should return id when given a symbol of the name' do
enum[:Name_1].should == 1
enum[:name_1].should == 1
context 'symbol ids' do
let(:enum) {
define_enum do
value :id => :one, :name => 'Name 1'
value :id => :two, :name => 'Name 2'
end
}

it 'should return name when given an id' do
enum[:one].should == 'Name 1'
end

it 'should return id when given a name' do
enum['Name 1'].should == :one
end

it 'should return id when given a symbol of the name' do
enum[:Name_1].should == :one
enum[:name_1].should == :one
end

context 'ids and names are similar' do
let(:enum) {
define_enum do
value :id => :one, :name => 'two'
value :id => :two, :name => 'three'
end
}

it 'should match on id before name' do
enum[:one].should == 'two'
enum[:two].should == 'three'
enum[:three].should == :two
end
end
end
end

Expand Down
29 changes: 29 additions & 0 deletions spec/active_enum/form_helpers/formtastic2_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,35 @@
output.should have_xpath('//option[@value=2]', :content => 'Female')
end

context 'with ids as symbols' do
before do
reset_class Person do
enumerate :sex do
value :id => :m, :name => 'Male'
value :id => :f, :name => 'Female'
end
end
end

it "should use enum input type for enumerated attribute" do
output = semantic_form_for(Person.new, :url => people_path) do |f|
concat f.input(:sex)
end
output.should have_selector('select#person_sex')
output.should have_xpath("//option[@value='m']", :content => 'Male')
output.should have_xpath("//option[@value='f']", :content => 'Female')
end

it "should use explicit :enum input type" do
output = semantic_form_for(Person.new, :url => people_path) do |f|
concat f.input(:sex, :as => :enum)
end
output.should have_selector('select#person_sex')
output.should have_xpath("//option[@value='m']", :content => 'Male')
output.should have_xpath("//option[@value='f']", :content => 'Female')
end
end

it "should not use enum input type if :as option indicates other type" do
output = semantic_form_for(Person.new, :url => people_path) do |f|
concat f.input(:sex, :as => :string)
Expand Down
30 changes: 30 additions & 0 deletions spec/active_enum/form_helpers/simple_form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,36 @@
output.should have_xpath('//option[@value=2]', :content => 'Female')
end

context 'with ids as symbols' do
before do
controller.stub!(:action_name).and_return('new')
reset_class Person do
enumerate :sex do
value :id => :m, :name => 'Male'
value :id => :f, :name => 'Female'
end
end
end

it "should use enum input type for enumerated attribute" do
output = simple_form_for(Person.new, :url => people_path) do |f|
concat f.input(:sex)
end
output.should have_selector('select#person_sex')
output.should have_xpath("//option[@value='m']", :content => 'Male')
output.should have_xpath("//option[@value='f']", :content => 'Female')
end

it "should use explicit :enum input type" do
output = simple_form_for(Person.new, :url => people_path) do |f|
concat f.input(:sex, :as => :enum)
end
output.should have_selector('select#person_sex')
output.should have_xpath("//option[@value='m']", :content => 'Male')
output.should have_xpath("//option[@value='f']", :content => 'Female')
end
end

it "should not use enum input type if :as option indicates other type" do
output = simple_form_for(Person.new, :url => people_path) do |f|
concat f.input(:sex, :as => :string)
Expand Down
8 changes: 7 additions & 1 deletion spec/active_enum/storage/i18n_store_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,24 @@ class TestI18nStoreEnum < ActiveEnum::Base; end
I18n.locale = :en
end

it 'should return the value for a given id' do
it 'should return the value for a given integer id' do
store.set 1, 'test'
store.get_by_id(1).should == [1, 'Testing']
end

it 'should return the value for a given symbol id' do
store.set :abc, 'test'
store.get_by_id(:abc).should == [:abc, 'Testing']
end

it 'should return the value with meta for a given id' do
store.set 1, 'test', :description => 'meta'
store.get_by_id(1).should == [1, 'Testing', { :description => 'meta' }]
end

it 'should return nil when id not found' do
store.get_by_id(1).should be_nil
store.get_by_id(:abc).should be_nil
end

it 'should return key when translation missing' do
Expand Down
8 changes: 7 additions & 1 deletion spec/active_enum/storage/memory_store_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,19 @@ class TestOtherAREnum < ActiveEnum::Base; end
end

describe "#get_by_id" do
it 'should return the value for a given id' do
it 'should return the value for a given integer id' do
store.set 1, 'test name', :description => 'meta'
store.get_by_id(1).should == [1, 'test name', {:description => "meta"}]
end

it 'should return the value for a given symbol id' do
store.set :abc, 'test name', :description => 'meta'
store.get_by_id(:abc).should == [:abc, 'test name', {:description => "meta"}]
end

it 'should return nil when id not found' do
store.get_by_id(1).should be_nil
store.get_by_id(:abc).should be_nil
end
end

Expand Down