immutable_attributes 1.1.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/.document +7 -0
- data/.gitignore +2 -0
- data/README +26 -0
- data/Rakefile +24 -0
- data/VERSION +1 -0
- data/immutable_attributes.gemspec +49 -0
- data/init.rb +2 -0
- data/install.rb +1 -0
- data/lib/immutable_attributes.rb +60 -0
- data/rails/init.rb +2 -0
- data/test/immutable_attributes_test.rb +31 -0
- metadata +65 -0
data/.document
ADDED
data/.gitignore
ADDED
data/README
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
ImmutableAttributes
|
4
|
+
===================
|
5
|
+
|
6
|
+
When you want to prevent certain attributes from being changed once set you can declare them as immutable:
|
7
|
+
|
8
|
+
class MyModel < ActiveRecord::Base
|
9
|
+
attr_immutable :permalink, :param_identifier
|
10
|
+
end
|
11
|
+
|
12
|
+
When MyModel.find(:first).permalink = 'anything' is called it will raise an ImmutableAttributeError
|
13
|
+
MyModel.new.permalink = 'works!' will properly set the value because the record is unsaved.
|
14
|
+
|
15
|
+
If you'd only like this to happen for certain conditions, and want to handle other attribute-writers, too (like update_attribute), you can use the validation.
|
16
|
+
|
17
|
+
validates_immutable :permalink
|
18
|
+
|
19
|
+
Configuration options for the validation:
|
20
|
+
* :message - A customer error message (default is: "can't be changed")
|
21
|
+
* :if - Specifies a method, proc, or string to call to determine if the validation should occure (e.g., :if => :allow_validation or :if => Proc.new{|user| user.signup_step > 2}. The method, proc or string should return or evaluate to a true or false value.
|
22
|
+
* :unless - Specifies a method, proc, or string to call to determine if the validation should not occure (e.g., :unless => :skip_validation or :unless => Proc.new{|user| user.signup_step <= 2}. The method, proc or string should return or evaluate to a true or false value.
|
23
|
+
|
24
|
+
Created by Jack Danger Canty @ http://6brand.com
|
25
|
+
Released under the same licence as Rails (MIT)
|
26
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "immutable_attributes"
|
8
|
+
gem.summary = %Q{Selected attributes are permanent once a record is created}
|
9
|
+
gem.description = %Q{Allows specified attributes to be freely overwritten _until_ the record is saved for the first time}
|
10
|
+
gem.email = "gems@6brand.com"
|
11
|
+
gem.homepage = "http://github.com/JackDanger/immutable_attributes"
|
12
|
+
gem.authors = ["Jack Danger Canty"]
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'rake/testtask'
|
19
|
+
task :test do
|
20
|
+
exec "ruby test/immutable_attributes_test.rb"
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default => :test
|
24
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.0
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{immutable_attributes}
|
8
|
+
s.version = "1.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jack Danger Canty"]
|
12
|
+
s.date = %q{2009-09-26}
|
13
|
+
s.description = %q{Allows specified attributes to be freely overwritten _until_ the record is saved for the first time}
|
14
|
+
s.email = %q{gems@6brand.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".document",
|
20
|
+
".gitignore",
|
21
|
+
"README",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"immutable_attributes.gemspec",
|
25
|
+
"init.rb",
|
26
|
+
"install.rb",
|
27
|
+
"lib/immutable_attributes.rb",
|
28
|
+
"rails/init.rb",
|
29
|
+
"test/immutable_attributes_test.rb"
|
30
|
+
]
|
31
|
+
s.homepage = %q{http://github.com/JackDanger/immutable_attributes}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.5}
|
35
|
+
s.summary = %q{Selected attributes are permanent once a record is created}
|
36
|
+
s.test_files = [
|
37
|
+
"test/immutable_attributes_test.rb"
|
38
|
+
]
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
|
+
s.specification_version = 3
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
45
|
+
else
|
46
|
+
end
|
47
|
+
else
|
48
|
+
end
|
49
|
+
end
|
data/init.rb
ADDED
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
puts IO.read(File.join(File.dirname(__FILE__), 'README'))
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'activerecord'
|
3
|
+
|
4
|
+
module ImmutableErrors
|
5
|
+
class ImmutableAttributeError < ActiveRecord::ActiveRecordError
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ImmutableAttributes
|
10
|
+
def attr_immutable(*args)
|
11
|
+
args.each do |meth|
|
12
|
+
class_eval do
|
13
|
+
define_method("#{meth}=") do |value|
|
14
|
+
new_record? || read_attribute(meth).nil? ?
|
15
|
+
write_attribute(meth, value) :
|
16
|
+
raise(ActiveRecord::ImmutableAttributeError, "#{meth} is immutable!")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def validates_immutable(*attr_names)
|
23
|
+
config = { :on => :update, :if => lambda {|x| true}, :message => "can't be changed" }
|
24
|
+
config.update(attr_names.extract_options!)
|
25
|
+
|
26
|
+
@immutables = attr_names
|
27
|
+
|
28
|
+
attr_names.each do |meth|
|
29
|
+
class_eval do
|
30
|
+
define_method("original_#{meth}") do
|
31
|
+
instance_variable_get("@original_#{meth}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class_eval do
|
37
|
+
def self.immutables
|
38
|
+
@immutables
|
39
|
+
end
|
40
|
+
|
41
|
+
def after_initialize; end;
|
42
|
+
|
43
|
+
def setup_originals
|
44
|
+
self.class.immutables.each do |attr_name|
|
45
|
+
instance_variable_set("@original_#{attr_name}", send(attr_name.to_s))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
after_initialize :setup_originals
|
50
|
+
end
|
51
|
+
|
52
|
+
validates_each(attr_names, config) do |record, attr_name, value|
|
53
|
+
next if record.send("original_#{attr_name.to_s}").nil?
|
54
|
+
record.errors.add(attr_name, config[:message]) if record.send("original_#{attr_name.to_s}") != record.send(attr_name.to_s)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
ActiveRecord.send :include, ImmutableErrors
|
60
|
+
ActiveRecord::Base.extend ImmutableAttributes
|
data/rails/init.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'activerecord'
|
4
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'immutable_attributes')
|
5
|
+
|
6
|
+
ActiveRecord::Base.establish_connection(
|
7
|
+
:adapter => "sqlite3",
|
8
|
+
:database => ":memory:"
|
9
|
+
)
|
10
|
+
ActiveRecord::Schema.define do
|
11
|
+
create_table :records do |table|
|
12
|
+
table.column :name, :string
|
13
|
+
table.column :body, :string
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Record < ActiveRecord::Base
|
18
|
+
attr_immutable :name
|
19
|
+
end
|
20
|
+
|
21
|
+
class ImmutableAttributesTest < Test::Unit::TestCase
|
22
|
+
|
23
|
+
def test_immutable_attribute_can_be_set
|
24
|
+
assert Record.new(:name => 'record name')
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_immutable_attribute_cannot_be_changed
|
28
|
+
record = Record.create!(:name => 'record name')
|
29
|
+
assert_raises(ActiveRecord::ImmutableAttributeError) { record.update_attributes(:name => 'new name') }
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: immutable_attributes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jack Danger Canty
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-26 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Allows specified attributes to be freely overwritten _until_ the record is saved for the first time
|
17
|
+
email: gems@6brand.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- .document
|
26
|
+
- .gitignore
|
27
|
+
- README
|
28
|
+
- Rakefile
|
29
|
+
- VERSION
|
30
|
+
- immutable_attributes.gemspec
|
31
|
+
- init.rb
|
32
|
+
- install.rb
|
33
|
+
- lib/immutable_attributes.rb
|
34
|
+
- rails/init.rb
|
35
|
+
- test/immutable_attributes_test.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/JackDanger/immutable_attributes
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options:
|
42
|
+
- --charset=UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.3.5
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: Selected attributes are permanent once a record is created
|
64
|
+
test_files:
|
65
|
+
- test/immutable_attributes_test.rb
|