mass_assignable 1.0.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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mass_assignable.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Derrick Reimer
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,79 @@
1
+ # MassAssignable
2
+
3
+ MassAssignable is a simple gem that adds Rails-like mass-assignment behavior
4
+ to ordinary Ruby objects. This gem has no external dependencies and works
5
+ everywhere.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'mass_assignable'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install mass_assignable
20
+
21
+ ## Usage
22
+
23
+ Simply include `MassAssignable` in your class and specify mass assignable
24
+ attributes using `attr_mass_assignable`. Any attributes not specified
25
+ will not be mass assignable.
26
+
27
+ ```ruby
28
+ require 'mass_assignable' # not needed with Rails
29
+
30
+ class Person
31
+ include MassAssignable
32
+
33
+ attr_accessor :name, :age, :height
34
+ attr_mass_assignable :name, :age
35
+ end
36
+ ```
37
+
38
+ Then, mass assignment is as easy as calling `attributes=`.
39
+
40
+ ```ruby
41
+ person = Person.new
42
+ person.attributes = { :name => "Derrick", :age => 24, :height => 77 }
43
+
44
+ person.name
45
+ # => "Derrick"
46
+
47
+ person.age
48
+ # => 24
49
+
50
+ person.height
51
+ # => nil
52
+ ```
53
+
54
+ Notice that `#height` is nil, because we didn't include it in our call to
55
+ `attr_mass_assignable`.
56
+
57
+ If you want an error to be raised when invalid mass assignment is attempted,
58
+ simply use `attr_mass_assignable!`.
59
+
60
+ ```ruby
61
+ class ParanoidPerson
62
+ include MassAssignable
63
+
64
+ attr_accessor :name, :age, :height
65
+ attr_mass_assignable! :name, :age
66
+ end
67
+
68
+ person = ParanoidPerson.new
69
+ person.attributes = { :height => 77 }
70
+ # => Raises a RuntimeError
71
+ ```
72
+
73
+ ## Contributing
74
+
75
+ 1. Fork it
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create new Pull Request
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "lib"
6
+ t.pattern = "test/**/*_test.rb"
7
+ t.verbose = true
8
+ end
9
+
10
+ desc "Run tests"
11
+ task :default => :test
@@ -0,0 +1,64 @@
1
+ module MassAssignable
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+ end
5
+
6
+ module ClassMethods
7
+ # Internal: Flag determining whether to raise an exception when
8
+ # you attempt to mass-assign attributes that are not allowed.
9
+ attr_accessor :raise_on_invalid_mass_assignment
10
+
11
+ # Internal: The Array of Symbols representing attributes that are
12
+ # mass assignable. This property is defined by the attr_assignable
13
+ # method.
14
+ attr_writer :mass_assignable_attributes
15
+
16
+ def mass_assignable_attributes
17
+ @mass_assignable_attributes ||= []
18
+ end
19
+
20
+ # Public: Accepts a list of symbols representing instance methods
21
+ # that allow mass-assignment.
22
+ #
23
+ # *attributes - An Array of symbols or strings.
24
+ #
25
+ # Returns nothing.
26
+ def attr_mass_assignable(*attributes)
27
+ self.raise_on_invalid_mass_assignment = false
28
+ self.mass_assignable_attributes ||= []
29
+ self.mass_assignable_attributes.push(*attributes)
30
+ end
31
+
32
+ # Public: Accepts a list of symbols representing instance methods
33
+ # that allow mass-assignment and will raise an exception if
34
+ # mass assignment is attempted for attributes not specified here.
35
+ #
36
+ # *attributes - An Array of symbols or strings.
37
+ #
38
+ # Returns nothing.
39
+ def attr_mass_assignable!(*attributes)
40
+ attr_mass_assignable(*attributes)
41
+ self.raise_on_invalid_mass_assignment = true
42
+ end
43
+ end
44
+
45
+ # Public: Assigns a Hash of attributes to their corresponding
46
+ # instance methods. If attributes are specified with attr_assignable,
47
+ # then only those attributes are allowed to be assigned.
48
+ #
49
+ # attribute_hash - A Hash of attribute values with symbol keys.
50
+ #
51
+ # Returns nothing.
52
+ def attributes=(attribute_hash)
53
+ paranoid = self.class.raise_on_invalid_mass_assignment
54
+ allowed = self.class.mass_assignable_attributes.map { |a| a.to_s }
55
+
56
+ attribute_hash.each do |key, value|
57
+ if allowed.include?(key.to_s)
58
+ send(:"#{key}=", value)
59
+ else
60
+ raise(RuntimeError, "Mass assignment error") if paranoid
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "mass_assignable"
7
+ gem.version = "1.0.0"
8
+ gem.authors = ["Derrick Reimer"]
9
+ gem.email = ["derrickreimer@gmail.com"]
10
+ gem.description = %q{Add Rails-like mass assignment to any Ruby object}
11
+ gem.summary = %q{MassAssignable provides mass assignment functionality to any Ruby object.}
12
+ gem.homepage = "https://github.com/djreimer/mass_assignable"
13
+
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.add_development_dependency "shoulda-context"
20
+ end
@@ -0,0 +1,114 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'mass_assignable'
3
+ require 'minitest/autorun'
4
+ require 'shoulda-context'
5
+
6
+ class MassAssignableTest < Test::Unit::TestCase
7
+ class Person
8
+ include MassAssignable
9
+
10
+ attr_accessor :name, :age, :height
11
+ attr_mass_assignable :name, :age, :height
12
+ end
13
+
14
+ class Car
15
+ include MassAssignable
16
+
17
+ attr_mass_assignable :make
18
+ attr_mass_assignable :model
19
+ end
20
+
21
+ class BlankClass
22
+ include MassAssignable
23
+ end
24
+
25
+ class NothingAssignable
26
+ include MassAssignable
27
+ attr_mass_assignable
28
+ end
29
+
30
+ class ParanoidNothingAssignable
31
+ include MassAssignable
32
+ attr_mass_assignable!
33
+ end
34
+
35
+ class ProtectedAttributes
36
+ include MassAssignable
37
+
38
+ attr_accessor :name, :age, :height
39
+ attr_mass_assignable :name
40
+ end
41
+
42
+ class ParanoidPerson
43
+ include MassAssignable
44
+
45
+ attr_accessor :name, :age, :height
46
+ attr_mass_assignable! :name, :age, :height
47
+ end
48
+
49
+ context ".attr_mass_assignable" do
50
+ should "set mass assignable attributes" do
51
+ assert_equal [:name, :age, :height], Person.mass_assignable_attributes
52
+ end
53
+
54
+ should "set mass assignable attribute to an empty array if not called" do
55
+ assert BlankClass.mass_assignable_attributes.is_a?(Array)
56
+ assert BlankClass.mass_assignable_attributes.empty?
57
+ end
58
+
59
+ should "set mass assignable attribute to an empty array if no arguments given" do
60
+ assert NothingAssignable.mass_assignable_attributes.is_a?(Array)
61
+ assert NothingAssignable.mass_assignable_attributes.empty?
62
+ end
63
+
64
+ should "append attributes on multiple calls" do
65
+ assert Car.mass_assignable_attributes.include?(:make)
66
+ assert Car.mass_assignable_attributes.include?(:model)
67
+ end
68
+
69
+ should "not raise an exception for invalid mass assignment attempts" do
70
+ person = Person.new
71
+ person.attributes = { :gender => "male" }
72
+ end
73
+ end
74
+
75
+ context ".attr_mass_assignable!" do
76
+ should "set mass assignable attributes" do
77
+ assert_equal [:name, :age, :height], ParanoidPerson.mass_assignable_attributes
78
+ end
79
+
80
+ should "set mass assignable attribute to an empty array if no arguments given" do
81
+ assert ParanoidNothingAssignable.mass_assignable_attributes.is_a?(Array)
82
+ assert ParanoidNothingAssignable.mass_assignable_attributes.empty?
83
+ end
84
+
85
+ should "raise an exception for invalid mass assignment attempts" do
86
+ assert_raises(RuntimeError) do
87
+ person = ParanoidPerson.new
88
+ person.attributes = { :gender => "male" }
89
+ end
90
+ end
91
+ end
92
+
93
+ context "#attributes=" do
94
+ should "set attribute values" do
95
+ person = Person.new
96
+ person.attributes = { :name => "Derrick", :age => 24, :height => 77 }
97
+ assert_equal "Derrick", person.name
98
+ assert_equal 24, person.age
99
+ assert_equal 77, person.height
100
+ end
101
+
102
+ should "not overwrite unspecified attributes" do
103
+ original_attr = { :name => "Derrick" }
104
+ new_attr = { :age => 24, :height => 77 }
105
+ person = Person.new
106
+ person.attributes = original_attr
107
+ person.attributes = new_attr
108
+
109
+ assert_equal "Derrick", person.name
110
+ assert_equal 24, person.age
111
+ assert_equal 77, person.height
112
+ end
113
+ end
114
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mass_assignable
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Derrick Reimer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: shoulda-context
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Add Rails-like mass assignment to any Ruby object
31
+ email:
32
+ - derrickreimer@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE.txt
40
+ - README.md
41
+ - Rakefile
42
+ - lib/mass_assignable.rb
43
+ - mass_assignable.gemspec
44
+ - test/mass_assignable_test.rb
45
+ homepage: https://github.com/djreimer/mass_assignable
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.23
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: MassAssignable provides mass assignment functionality to any Ruby object.
69
+ test_files:
70
+ - test/mass_assignable_test.rb