Add query methods in ActiveRecord::Base.store for convenience #6866

Closed
wants to merge 2 commits into
from
View
18 activerecord/lib/active_record/store.rb
@@ -18,11 +18,12 @@ module ActiveRecord
# Examples:
#
# class User < ActiveRecord::Base
- # store :settings, accessors: [ :color, :homepage ], coder: JSON
+ # store :settings, accessors: [ :color, :homepage, :editor ], coder: JSON
# end
#
- # u = User.new(color: 'black', homepage: '37signals.com')
+ # u = User.new(color: 'black', homepage: '37signals.com', editor: true)
# u.color # Accessor stored attribute
+ # u.editor? # Query method for convenience
# u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
#
# # There is no difference between strings and symbols for accessing custom attributes
@@ -36,7 +37,7 @@ module ActiveRecord
#
# The stored attribute names can be retrieved using +stored_attributes+.
#
- # User.stored_attributes[:settings] # [:color, :homepage]
+ # User.stored_attributes[:settings] # [:color, :homepage, :editor]
#
# == Overwriting default accessors
#
@@ -83,6 +84,17 @@ def store_accessor(store_attribute, *keys)
define_method(key) do
read_store_attribute(store_attribute, key)
end
+
+ define_method("#{key}?") do
+ value = send(key)
+ if value.blank?
+ false
+ elsif value.is_a?(Numeric)
+ !value.zero?
+ else
+ !!value
+ end
+ end
end
end
View
24 activerecord/test/cases/store_test.rb
@@ -6,14 +6,36 @@ class StoreTest < ActiveRecord::TestCase
fixtures :'admin/users'
setup do
- @john = Admin::User.create!(:name => 'John Doe', :color => 'black', :remember_login => true, :height => 'tall', :is_a_good_guy => true)
+ @john = Admin::User.create!(:name => 'John Doe',
+ :color => 'black',
+ :remember_login => true,
+ :height => 'tall',
+ :is_a_good_guy => true,
+ :is_a_bad_guy => false,
+ :empty_thing => "",
+ :zero_thing => 0)
end
test "reading store attributes through accessors" do
assert_equal 'black', @john.color
assert_nil @john.homepage
end
+ test "query store attributes through query accessors" do
+ assert_equal true, @john.is_a_good_guy?
+ assert_equal false, @john.is_a_bad_guy?
+ assert_equal true, @john.color?
+ assert_equal false, @john.homepage?
+ end
+
+ test "quering attributes should return false in special cases" do
+ assert_equal false, @john.empty_thing?
+ assert_equal false, @john.zero_thing?
+
+ @john.zero_thing = 0.0
+ assert_equal false, @john.zero_thing?
+ end
+
test "writing store attributes through accessors" do
@john.color = 'red'
@john.homepage = '37signals.com'
View
3 activerecord/test/models/admin/user.rb
@@ -17,8 +17,9 @@ def load(s)
store :settings, :accessors => [ :color, :homepage ]
store_accessor :settings, :favorite_food
store :preferences, :accessors => [ :remember_login ]
+ store :quering, :accessors => [ :empty_thing, :zero_thing ]
store :json_data, :accessors => [ :height, :weight ], :coder => Coder.new
- store :json_data_empty, :accessors => [ :is_a_good_guy ], :coder => Coder.new
+ store :json_data_empty, :accessors => [ :is_a_good_guy, :is_a_bad_guy ], :coder => Coder.new
def phone_number
read_store_attribute(:settings, :phone_number).gsub(/(\d{3})(\d{3})(\d{4})/,'(\1) \2-\3')
View
1 activerecord/test/schema/schema.rb
@@ -38,6 +38,7 @@ def create_table(*args, &block)
create_table :admin_users, :force => true do |t|
t.string :name
t.string :settings, :null => true, :limit => 1024
+ t.text :quering, :null => true, :limit => 1024
# MySQL does not allow default values for blobs. Fake it out with a
# big varchar below.
t.string :preferences, :null => true, :default => '', :limit => 1024