attribute_mapper 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.kick ADDED
@@ -0,0 +1,6 @@
1
+ recipe :ruby
2
+
3
+ startup { log "Here we go." }
4
+
5
+ Ruby.test_options << "-Itest"
6
+ Ruby.test_options << "-rubygems"
data/HISTORY.rdoc ADDED
@@ -0,0 +1,8 @@
1
+ = 1.2.0 (2010-02-23)
2
+
3
+ * Verified compatibility with +update_attributes+ and +attr_accessible+.
4
+ * Add +_options+ helper to make generating select forms for mappings easier
5
+
6
+ = 1.1.1 (2010-01-08)
7
+
8
+ * Changelog epoch.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007-2009 Marcel Molina, Jr., Bruce Williams, Adam Keys
1
+ Copyright (c) 2007-2010 Marcel Molina, Jr., Bruce Williams, Adam Keys
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of
4
4
  this software and associated documentation files (the "Software"), to deal in
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- :minor: 1
3
- :patch: 1
2
+ :minor: 2
3
+ :patch: 0
4
4
  :build:
5
5
  :major: 1
@@ -1,46 +1,25 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
5
2
 
6
3
  Gem::Specification.new do |s|
7
4
  s.name = %q{attribute_mapper}
8
- s.version = "1.1.1"
5
+ s.version = "0.9.1"
9
6
 
10
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
8
  s.authors = ["Marcel Molina Jr.", "Bruce Williams", "Adam Keys"]
12
- s.date = %q{2010-01-08}
9
+ s.date = %q{2009-03-10}
13
10
  s.description = %q{Provides a transparent interface for mapping symbolic representations to a column in the database of a more primitive type.}
14
11
  s.email = %q{adamkkeys@gmail.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.md"
18
- ]
19
- s.files = [
20
- ".gitignore",
21
- "LICENSE",
22
- "README.md",
23
- "Rakefile",
24
- "VERSION.yml",
25
- "attribute_mapper.gemspec",
26
- "init.rb",
27
- "lib/attribute_mapper.rb",
28
- "test/attribute_mapper_test.rb",
29
- "test/test_helper.rb"
30
- ]
12
+ s.files = ["README.md", "VERSION.yml", "lib/attribute_mapper.rb", "test/attribute_mapper_test.rb"]
13
+ s.has_rdoc = true
31
14
  s.homepage = %q{http://github.com/therealadam/attribute_mapper}
32
- s.rdoc_options = ["--charset=UTF-8"]
15
+ s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
33
16
  s.require_paths = ["lib"]
34
- s.rubygems_version = %q{1.3.5}
17
+ s.rubygems_version = %q{1.3.1}
35
18
  s.summary = %q{Map symbolic types to primitive types and stash them in a column.}
36
- s.test_files = [
37
- "test/attribute_mapper_test.rb",
38
- "test/test_helper.rb"
39
- ]
40
19
 
41
20
  if s.respond_to? :specification_version then
42
21
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
- s.specification_version = 3
22
+ s.specification_version = 2
44
23
 
45
24
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
46
25
  else
@@ -48,4 +27,3 @@ Gem::Specification.new do |s|
48
27
  else
49
28
  end
50
29
  end
51
-
@@ -7,89 +7,121 @@ module AttributeMapper
7
7
 
8
8
  module ClassMethods # @private
9
9
 
10
- # Map a column in your table to a human-friendly attribute on your model. When
11
- # ++attribute is accessed, it will return the key from the mapping hash. When
12
- # the attribute is updated, the value from the mapping hash is written to the
13
- # database.
10
+ # Map a column in your table to a human-friendly attribute on your
11
+ # model. When +attribute+ is accessed, it will return the key
12
+ # from the mapping hash. When the attribute is updated, the value
13
+ # from the mapping hash is written to the database.
14
14
  #
15
15
  # A class method is also added providing access to the mapping
16
- # hash, i.e. defining an attribute ++status++ will add a
17
- # ++statuses++ class method that returns the hash passed to the
18
- # ++:to++ option.
16
+ # hash, i.e. defining an attribute +status+ will add a
17
+ # +statuses+ class method that returns the hash passed to the
18
+ # +:to+ option.
19
19
  #
20
- # Predicates are also added to each object for each attribute. If you have a key
21
- # ++open++ in your mapping, your objects will have an ++open?++ method that
22
- # returns true if the attribute value is ++:open++
20
+ # Predicates are also added to each object for each attribute. If
21
+ # you have a key +open+ in your mapping, your objects will have
22
+ # an +open?+ method that returns true if the attribute value is
23
+ # +:open+
23
24
  #
24
- # @example Define a Ticket model with a status column that maps to open or closed
25
+ # Each attribute you map generates an options method, suitable for
26
+ # use in form helpers. If you define an attribute +status+,
27
+ # instances of your model will have a +status_options+ method
28
+ # that returns a sorted array of arrays containing
29
+ # humanized-option-name/value pairs. By default this array is
30
+ # sorted by the option name (closed/open/etc.) If you'd rather
31
+ # sort by value, pass +false+ to the options method. This method
32
+ # also will set the selected option for records where the
33
+ # attribute is already set.
34
+ #
35
+ # @example Define a Ticket model with a status column:
25
36
  # map_attribute :status, :to => {:open => 1, :closed => 2}
26
37
  #
27
38
  # @param [String] attribute the column to map on
28
39
  # @param [Hash] options the options for this attribute
29
- # @option options [Hash] :to The enumeration to use for this attribute. See example above.
40
+ # @option options [Hash] :to The enumeration to use for this
41
+ # attribute. See example above.
30
42
  def map_attribute(attribute, options)
31
43
  mapping = options[:to]
32
44
  verify_existence_of attribute
33
45
  add_accessor_for attribute, mapping
34
46
  add_predicates_for attribute, mapping.keys
35
47
  override attribute
48
+ add_options_helper_for attribute, mapping
36
49
  end
37
50
 
38
51
  private
39
- def add_accessor_for(attribute, mapping)
40
- class_eval(<<-EVAL)
41
- class << self
42
- def #{attribute.to_s.pluralize}
43
- #{mapping.inspect}
44
- end
52
+
53
+ def add_accessor_for(attribute, mapping)
54
+ class_eval(<<-EVAL)
55
+ class << self
56
+ def #{attribute.to_s.pluralize}
57
+ #{mapping.inspect}
45
58
  end
46
- EVAL
47
59
  end
60
+ EVAL
61
+ end
48
62
 
49
- def add_predicates_for(attribute, names)
50
- names.each do |name|
51
- class_eval(<<-RUBY)
52
- def #{name}?
53
- self.#{attribute} == :#{name}
54
- end
55
- RUBY
63
+ def add_predicates_for(attribute, names)
64
+ names.each do |name|
65
+ class_eval(<<-RUBY)
66
+ def #{name}?
67
+ self.#{attribute} == :#{name}
56
68
  end
69
+ RUBY
70
+ end
71
+ end
72
+
73
+ def add_options_helper_for(attribute, mapping)
74
+ class_eval(<<-EVAL, __FILE__, __LINE__)
75
+ def #{attribute}_options(sort_by_keys=true)
76
+ options = self.class.#{attribute.to_s.pluralize}.sort { |l, r|
77
+ sort_by_keys ? l.first.to_s <=> r.first.to_s : l.last <=> r.last
78
+ }.map { |f|
79
+ [f[0].to_s.humanize, f[0]]
80
+ }
81
+ self.#{attribute}.present? ? [options, {:selected => self.#{attribute}}] : [options]
57
82
  end
83
+ EVAL
84
+ end
85
+
86
+ def override(*args)
87
+ override_getters *args
88
+ override_setters *args
89
+ end
90
+
91
+ def override_getters(attribute)
92
+ class_eval(<<-EVAL)
93
+ def #{attribute}
94
+ self.class.#{attribute.to_s.pluralize}.invert[read_attribute(:#{attribute})]
95
+ end
96
+ EVAL
97
+ end
98
+
99
+ def override_setters(attribute)
100
+ class_eval(<<-EVAL)
101
+ def #{attribute}=(raw_value)
102
+ value = resolve_value_of :#{attribute}, raw_value
103
+ write_attribute(:#{attribute}, value)
104
+ end
105
+ EVAL
106
+ end
107
+
108
+ def verify_existence_of(attribute)
109
+ raise ArgumentError, "`#{attribute}' is not an attribute of `#{self}'" unless column_names.include?(attribute.to_s)
110
+ end
58
111
 
59
- def override(*args)
60
- override_getters *args
61
- override_setters *args
62
- end
63
-
64
- def override_getters(attribute)
65
- class_eval(<<-EVAL)
66
- def #{attribute}
67
- self.class.#{attribute.to_s.pluralize}.invert[read_attribute(:#{attribute})]
68
- end
69
- EVAL
70
- end
71
-
72
- def override_setters(attribute)
73
- class_eval(<<-EVAL)
74
- def #{attribute}=(raw_value)
75
- value = resolve_value_of :#{attribute}, raw_value
76
- write_attribute(:#{attribute}, value)
77
- end
78
- EVAL
79
- end
80
-
81
- def verify_existence_of(attribute)
82
- raise ArgumentError, "`#{attribute}' is not an attribute of `#{self}'" unless column_names.include?(attribute.to_s)
83
- end
84
112
  end
85
113
 
86
114
  module InstanceMethods
115
+
87
116
  private
88
- def resolve_value_of(attribute, raw_value)
89
- check_value = raw_value.is_a?(String) ? raw_value.to_sym : raw_value
90
- mapping = self.class.send(attribute.to_s.pluralize)
91
- raise ArgumentError, "`#{check_value}' not present in attribute mapping `#{mapping.inspect}'" unless mapping.to_a.flatten.include? check_value
92
- mapping[check_value] || check_value
93
- end
117
+
118
+ def resolve_value_of(attribute, raw_value)
119
+ check_value = raw_value.is_a?(String) ? raw_value.to_sym : raw_value
120
+ mapping = self.class.send(attribute.to_s.pluralize)
121
+ raise ArgumentError, "`#{check_value}' not present in attribute mapping `#{mapping.inspect}'" unless mapping.to_a.flatten.include? check_value
122
+ mapping[check_value] || check_value
123
+ end
124
+
94
125
  end
126
+
95
127
  end
@@ -68,7 +68,34 @@ class AttributeMapperTest < Test::Unit::TestCase
68
68
  ticket.status = 500
69
69
  end
70
70
  end
71
+
72
+ should "work with mass assignment" do
73
+ ticket.update_attributes(:status => :open, :name => 'Red is too red')
74
+ end
75
+
76
+ should "work with attr_accessible" do
77
+ new_ticket = Class.new(ActiveRecord::Base) do
78
+ set_table_name "tickets"
71
79
 
80
+ include AttributeMapper
81
+ map_attribute :status, :to => {:open => 1, :closed => 2}
82
+
83
+ attr_accessible :status
84
+ end
85
+
86
+ t = new_ticket.new
87
+ t.status = :open
88
+
89
+ assert_equal :open, t.status
90
+ end
91
+
92
+ should "provide a helper for forms" do
93
+ assert_equal [[["Closed", :closed], ["Open", :open]]], ticket.status_options
94
+ assert_equal [[["Open", :open], ["Closed", :closed]]], ticket.status_options(false)
95
+ ticket.status = :open
96
+ assert_equal [[["Open", :open], ["Closed", :closed]], {:selected => :open}], ticket.status_options(false)
97
+ end
98
+
72
99
  end
73
100
 
74
101
  #######
data/test/test_helper.rb CHANGED
@@ -12,6 +12,7 @@ ActiveRecord::Base.establish_connection(
12
12
  ActiveRecord::Schema.define do
13
13
  create_table :tickets do |table|
14
14
  table.column :status, :integer
15
+ table.column :name, :string
15
16
  end
16
17
  end
17
18
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribute_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcel Molina Jr.
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2010-01-08 00:00:00 -06:00
14
+ date: 2010-02-23 00:00:00 -06:00
15
15
  default_executable:
16
16
  dependencies: []
17
17
 
@@ -26,6 +26,8 @@ extra_rdoc_files:
26
26
  - README.md
27
27
  files:
28
28
  - .gitignore
29
+ - .kick
30
+ - HISTORY.rdoc
29
31
  - LICENSE
30
32
  - README.md
31
33
  - Rakefile