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 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
+
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe ValidatableAssociations do
4
+
5
+ it "definitely needs some tests"
6
+
7
+ end
@@ -0,0 +1,5 @@
1
+ require "rubygems"
2
+ gem "rspec", ">= 1.2.8"
3
+ require "spec"
4
+ require "validatable"
5
+ require File.join(File.dirname(__FILE__), "..", "lib", "validatable_associations")
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