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 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