validatable_associations 0.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/README.rdoc +56 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/validatable_associations.rb +117 -0
- data/spec/lib/validatable_associations_spec.rb +7 -0
- data/spec/spec_helper.rb +5 -0
- metadata +87 -0
data/README.rdoc
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
= ValidatableAssociations
|
2
|
+
|
3
|
+
ValidatableAssociations is an add-on to Jay Fields
|
4
|
+
{Validatable}[http://validatable.rubyforge.org] library. This add-on lets you
|
5
|
+
specify associations to other validatable classes and allows you to set up a
|
6
|
+
decent validatable structure.
|
7
|
+
|
8
|
+
== Install
|
9
|
+
|
10
|
+
$ script/plugin install git://github.com/rubiii/validatable_associations.git
|
11
|
+
|
12
|
+
== Associations
|
13
|
+
|
14
|
+
A very simple example of a "User has one Gorilla" association:
|
15
|
+
|
16
|
+
class User
|
17
|
+
include Validatable
|
18
|
+
include ValidatableAssociations
|
19
|
+
|
20
|
+
has_one :gorilla
|
21
|
+
|
22
|
+
attr_accessor :username, :password
|
23
|
+
|
24
|
+
validates_presence_of :username
|
25
|
+
validates_length_of :password, :minimum => 6
|
26
|
+
end
|
27
|
+
|
28
|
+
class Gorilla
|
29
|
+
include Validatable
|
30
|
+
include ValidatableAssociations
|
31
|
+
|
32
|
+
attr_accessor :name, :size
|
33
|
+
|
34
|
+
validates_presence_of :name
|
35
|
+
validates_numericality_of :size
|
36
|
+
end
|
37
|
+
|
38
|
+
==== Currently implemented associations:
|
39
|
+
|
40
|
+
The first version of this add-on only includes has_one associations.
|
41
|
+
I intend to only add more associations if I need them myself or if anyone convinces
|
42
|
+
me that he really needs support for another type of association.
|
43
|
+
|
44
|
+
== Validation
|
45
|
+
|
46
|
+
Calling the valid? method (provided by the Validatable library) on an instance of
|
47
|
+
one of your validatable Classes will also run the validations off all associations
|
48
|
+
of the Class.
|
49
|
+
|
50
|
+
== Mass-assignment
|
51
|
+
|
52
|
+
You can use mass-assignment to assign multiple values to your Class at once.
|
53
|
+
This also includes every one of its associations.
|
54
|
+
|
55
|
+
user = User.new :username => "apricot", :password => "secret",
|
56
|
+
:gorilla => { :name => "Joe", :size => 4411 }
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake"
|
3
|
+
require "spec/rake/spectask"
|
4
|
+
require "rake/rdoctask"
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
Spec::Rake::SpecTask.new do |spec|
|
9
|
+
spec.spec_files = FileList["spec/**/*_spec.rb"]
|
10
|
+
spec.spec_opts << "--color"
|
11
|
+
end
|
12
|
+
|
13
|
+
Rake::RDocTask.new do |rdoc|
|
14
|
+
rdoc.title = "ValidatableAssociations"
|
15
|
+
rdoc.rdoc_dir = "rdoc"
|
16
|
+
rdoc.main = "README.rdoc"
|
17
|
+
rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
18
|
+
rdoc.options = ["--line-numbers", "--inline-source"]
|
19
|
+
end
|
20
|
+
|
21
|
+
begin
|
22
|
+
require "jeweler"
|
23
|
+
Jeweler::Tasks.new do |spec|
|
24
|
+
spec.name = "validatable_associations"
|
25
|
+
spec.author = "Daniel Harrington"
|
26
|
+
spec.email = "me@rubiii.com"
|
27
|
+
spec.homepage = "http://github.com/rubiii/validatable_associations"
|
28
|
+
spec.summary = "Association add-on for the Validatable gem"
|
29
|
+
spec.description = spec.summary
|
30
|
+
|
31
|
+
spec.files = FileList["init.rb", "[A-Z]*", "{lib,spec}/**/*.{rb,xml}"]
|
32
|
+
|
33
|
+
spec.rdoc_options += [
|
34
|
+
"--title", "validatable_associations",
|
35
|
+
"--main", "README.rdoc",
|
36
|
+
"--line-numbers",
|
37
|
+
"--inline-source"
|
38
|
+
]
|
39
|
+
|
40
|
+
spec.add_development_dependency("validatable", "1.6.7")
|
41
|
+
spec.add_development_dependency("rspec", ">= 1.2.8")
|
42
|
+
end
|
43
|
+
rescue LoadError
|
44
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
45
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "validatable_associations"
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# == ValidatableAssociations
|
2
|
+
#
|
3
|
+
# ValidatableAssociations is an add-on to the Validatable gem by Jay Fields.
|
4
|
+
# It adds the most common association methods provided by Rails to your
|
5
|
+
# validatable Class and allows to set up a decent validatable structure.
|
6
|
+
module ValidatableAssociations
|
7
|
+
|
8
|
+
# ValidatableAssociations::ClassMethods
|
9
|
+
#
|
10
|
+
# Includes class methods for setting up the associations.
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
# Reader/writer method for has_one associations. Sets 1-n +associations+
|
14
|
+
# or defaults to return all previously specified associations if no
|
15
|
+
# parameters were given.
|
16
|
+
def has_one(*associations)
|
17
|
+
@has_one = [] unless @has_one
|
18
|
+
return @has_one if associations.empty?
|
19
|
+
@has_one = associations.map { |association| association.to_s }
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(base) #:nodoc:
|
25
|
+
base.extend(ClassMethods)
|
26
|
+
end
|
27
|
+
|
28
|
+
# The initialize method handles mass-assignment of a given Hash of
|
29
|
+
# +attributes+ to their instance variables.
|
30
|
+
def initialize(attributes = {})
|
31
|
+
return if !attributes || attributes.empty?
|
32
|
+
attributes.each { |ivar, value| assign_to(ivar, value) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Catches calls to undefined methods. Checks if the +method+ called matches
|
36
|
+
# a reader/writer method of an association and handles the read/write process.
|
37
|
+
# Delegates to super otherwise.
|
38
|
+
def method_missing(method, *args)
|
39
|
+
association_name = to_association_name(method)
|
40
|
+
super unless self.class.has_one.include? association_name
|
41
|
+
|
42
|
+
association_to_set = find_or_create_association(association_name, args[0])
|
43
|
+
self.instance_variable_set("@#{association_name}", association_to_set)
|
44
|
+
association_to_set
|
45
|
+
rescue NameError
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns whether the validations of this model and all associated models
|
50
|
+
# passed successfully.
|
51
|
+
def valid?
|
52
|
+
validate_associations
|
53
|
+
super && associations_valid?
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Assigns a given +value+ to a given +ivar+. Tries to use the writer method
|
59
|
+
# for the given instance variable and defaults to setting it directly in case
|
60
|
+
# no writer method was found.
|
61
|
+
def assign_to(ivar, value)
|
62
|
+
if assign_via_writer? ivar
|
63
|
+
self.send("#{ivar}=", value)
|
64
|
+
else
|
65
|
+
self.instance_variable_set("@#{ivar}", value)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Checks whether a given +ivar+ should be assigned via an existing writer
|
70
|
+
# method or directly.
|
71
|
+
def assign_via_writer?(ivar)
|
72
|
+
self.methods.include?("#{ivar}=") || self.class.has_one.include?(ivar)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Takes an +association_name+ and returns an existing association matching
|
76
|
+
# the given name. Instantiates a new association in case it hasn't been
|
77
|
+
# initialized already or in case of given +arguments+.
|
78
|
+
def find_or_create_association(association_name, arguments = nil)
|
79
|
+
if arguments
|
80
|
+
to_constant(association_name).new arguments
|
81
|
+
else
|
82
|
+
association = self.instance_variable_get("@#{association_name}")
|
83
|
+
association = to_constant(association_name).new unless association
|
84
|
+
association
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Validates all models associated with this model and stores the results.
|
89
|
+
def validate_associations
|
90
|
+
@association_validity = self.class.has_one.map do |association|
|
91
|
+
self.send(association).valid?
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns whether the validations of all models associated with this model
|
96
|
+
# passed successfully.
|
97
|
+
def associations_valid?
|
98
|
+
!@association_validity.include?(false)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Expects the name of a reader/writer +method+ and turns it into a valid
|
102
|
+
# name for an association.
|
103
|
+
def to_association_name(method)
|
104
|
+
association_name = method.to_s
|
105
|
+
association_name.slice!(-1) if association_name[-1, 1] == "="
|
106
|
+
association_name
|
107
|
+
end
|
108
|
+
|
109
|
+
# Converts a given +symbol+ from snake_case into an existing Constant.
|
110
|
+
# Note that the constanize method might raise a NameError in case the given
|
111
|
+
# symbol could not be mapped to a Constant.
|
112
|
+
def to_constant(symbol)
|
113
|
+
symbol.to_s.camelize.constantize
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: validatable_associations
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Harrington
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-21 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: validatable
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - "="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.6.7
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.8
|
34
|
+
version:
|
35
|
+
description: Association add-on for the Validatable gem
|
36
|
+
email: me@rubiii.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- README.rdoc
|
45
|
+
- Rakefile
|
46
|
+
- VERSION
|
47
|
+
- init.rb
|
48
|
+
- lib/validatable_associations.rb
|
49
|
+
- spec/lib/validatable_associations_spec.rb
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://github.com/rubiii/validatable_associations
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --charset=UTF-8
|
58
|
+
- --title
|
59
|
+
- validatable_associations
|
60
|
+
- --main
|
61
|
+
- README.rdoc
|
62
|
+
- --line-numbers
|
63
|
+
- --inline-source
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: "0"
|
71
|
+
version:
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: "0"
|
77
|
+
version:
|
78
|
+
requirements: []
|
79
|
+
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 1.3.5
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: Association add-on for the Validatable gem
|
85
|
+
test_files:
|
86
|
+
- spec/lib/validatable_associations_spec.rb
|
87
|
+
- spec/spec_helper.rb
|