mass_assignable 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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