Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

works on ruby 1.9.2

  • Loading branch information...
commit 900f903e8198e1ff5e3443643321eced8174d8b0 1 parent c0ead77
Kristian Mandrup authored
4 Gemfile
... ... @@ -1,5 +1,9 @@
1 1 source 'https://rubygems.org'
2 2
  3 +group :test do
  4 + gem 'rspec'
  5 +end
  6 +
3 7 gemspec
4 8
5 9 group :metrics do
12 README.md
Source Rendered
@@ -37,20 +37,24 @@ You can create classes extended with virtus and define attributes:
37 37 class User
38 38 include Virtus
39 39
40   - attributes :name, :title, String
  40 + attributes :first_name, :last_name, String
  41 + attributes :allow_pets, :allow_smoking, :allow_drinking, Boolean, :as => :rule_options
  42 +
41 43 attribute :age, Integer
42 44 attribute :birthday, DateTime
43 45 end
44 46
45   -user = User.new(:name => 'Piotr', :age => 28)
46   -user.attribute_set # => { :name => "Piotr", :age => 28 }
  47 +user = User.new(:first_name => 'Piotr', :age => 28)
  48 +user.attribute_set # => { :first_name => "Piotr", :age => 28 }
47 49
48   -user.name # => "Piotr"
  50 +user.first_name # => "Piotr"
49 51
50 52 user.age = '28' # => 28
51 53 user.age.class # => Fixnum
52 54
53 55 user.birthday = 'November 18th, 1983' # => #<DateTime: 1983-11-18T00:00:00+00:00 (4891313/2,0/1,2299161)>
  56 +
  57 +User.rule_options # => [:allow_pets, :allow_smoking, :allow_drinking]
54 58 ```
55 59
56 60 ### Using Virtus with Modules
2  Rakefile
... ... @@ -1,6 +1,6 @@
1 1 require 'rake'
2 2
3   -FileList['tasks/**/*.rake'].each { |task| import task }
  3 +FileList['tasks/**/spec.rake'].each { |task| import task }
4 4
5 5 desc 'Default: run all specs'
6 6 task :default => :spec
9 lib/virtus/attribute.rb
@@ -60,10 +60,13 @@ class Attribute
60 60 #
61 61 # @api private
62 62 def self.build(*args)
  63 + # puts "build: #{args}"
63 64 options = args.extract_options!
64 65 type_arg = args.last
65   - type = case type_arg.class.to_s
66   - when 'Symbol' #, 'String'
  66 + type = if type_arg.kind_of?(Class)
  67 + args.pop
  68 + # if no type argument, default to Object
  69 + elsif type_arg.class.to_s == 'Symbol'
67 70 Object
68 71 else
69 72 args.pop
@@ -71,7 +74,7 @@ def self.build(*args)
71 74 attrs = args.map do |name|
72 75 build_one name, type, options
73 76 end
74   - attrs.size == 1 ? attrs.first : attrs
  77 + attrs.size == 1 ? attrs.first : attrs.flatten
75 78 end
76 79
77 80 def self.build_one(name, type = Object, options = {})
18 lib/virtus/extensions.rb
@@ -49,11 +49,25 @@ def self.extended(object)
49 49 #
50 50 # @api public
51 51 def attribute(*args)
52   - attributes = Attribute.build(*args)
53   - [attributes].flatten.each {|attribute| virtus_add_attribute(attribute) }
  52 + opts = args.dup.extract_options!
  53 +
  54 + attributes = [Attribute.build(*args)].flatten
  55 + attributes.each {|attribute| virtus_add_attribute(attribute) }
  56 +
  57 + clazz_meth = opts.delete(:as) if opts[:as]
  58 + create_attribute_group clazz_meth, attributes if clazz_meth
  59 +
54 60 self
55 61 end
56 62
  63 + def create_attribute_group name, *attrs
  64 + singleton_class.class_eval do
  65 + define_method name do
  66 + attrs.flatten.map &:name
  67 + end
  68 + end
  69 + end
  70 +
57 71 # The list of writer methods that can be mass-assigned to in #attributes=
58 72 #
59 73 # @return [Set]
21 spec/integration/defining_attributes_spec.rb
@@ -7,6 +7,8 @@ module Examples
7 7 class Person
8 8 include Virtus
9 9
  10 + attributes :allow_pets, :allow_smoking, Boolean, :as => :rule_options
  11 +
10 12 attributes :name, :title, String
11 13 attribute :age, Integer
12 14 attribute :doctor, Boolean
@@ -41,7 +43,17 @@ class Manager < Person
41 43 end
42 44
43 45 context 'with attributes' do
44   - let(:attributes) { {:name => 'Jane', :title => 'Mr', :age => 45, :doctor => true, :salary => BigDecimal.new(4500) } }
  46 + let(:attributes) do
  47 + {
  48 + :allow_pets => true,
  49 + :allow_smoking => false,
  50 + :name => 'Jane',
  51 + :title => 'Mr',
  52 + :age => 45,
  53 + :doctor => true,
  54 + :salary => BigDecimal.new('4500.0')
  55 + }
  56 + end
45 57 subject { Examples::Person.new(attributes) }
46 58
47 59 specify "#attributes returns the object's attributes as a hash" do
@@ -53,6 +65,13 @@ class Manager < Person
53 65 end
54 66 end
55 67
  68 + context 'attribute group :rule_options defined' do
  69 + subject { Examples::Person }
  70 + specify ":as otion creates class method that returns attributes in rule group" do
  71 + subject.rule_options.should == [:allow_pets, :allow_smoking]
  72 + end
  73 + end
  74 +
56 75 context 'inheritance' do
57 76 specify 'inherits all the attributes from the base class' do
58 77 fred = Examples::Manager.new(:name => 'Fred', :age => 29)

0 comments on commit 900f903

Please sign in to comment.
Something went wrong with that request. Please try again.