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