attribute_mapper 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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