has_many_emails 0.2.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/.gitignore +2 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +62 -0
- data/Rakefile +67 -0
- data/VERSION +1 -0
- data/app/models/email_address.rb +49 -0
- data/has_many_emails.gemspec +81 -0
- data/init.rb +1 -0
- data/lib/generators/USAGE +8 -0
- data/lib/generators/has_many_emails_generator.rb +36 -0
- data/lib/generators/templates/create_email_address.rb +33 -0
- data/lib/has_many_emails.rb +27 -0
- data/lib/has_many_emails/class_methods.rb +11 -0
- data/lib/has_many_emails/instance_methods.rb +87 -0
- data/rails/init.rb +8 -0
- data/spec/db/create_db.rb +40 -0
- data/spec/db/database.yml +3 -0
- data/spec/db/models/user.rb +11 -0
- data/spec/debug.log +1 -0
- data/spec/factories.rb +9 -0
- data/spec/models/email_spec.rb +43 -0
- data/spec/models/exampels_spec.rb +54 -0
- data/spec/models/user_emails_spec.rb +70 -0
- data/spec/models/user_spec.rb +174 -0
- data/spec/spec_helper.rb +30 -0
- data/test/helper.rb +10 -0
- data/test/test_has_many_emails.rb +7 -0
- metadata +129 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
= has_many_emails
|
2
|
+
|
3
|
+
Add multiply emails to the +User+ model without changing the +email+ attribute behaviour.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
|
8
|
+
1. Install the plugin
|
9
|
+
|
10
|
+
$ rails plugin install http://..
|
11
|
+
|
12
|
+
2. Add to you +User+ class:
|
13
|
+
|
14
|
+
class User < ActiveRecord::Base
|
15
|
+
...
|
16
|
+
has_many_emails
|
17
|
+
...
|
18
|
+
|
19
|
+
3. Generate migration:
|
20
|
+
|
21
|
+
$ rails generate has_many_emails
|
22
|
+
|
23
|
+
4. Migrate.
|
24
|
+
|
25
|
+
$ rake db:migrate
|
26
|
+
|
27
|
+
It creates the +email_addresses+ table.
|
28
|
+
|
29
|
+
== Examples
|
30
|
+
|
31
|
+
> u = User.new(:name=>'Bob')
|
32
|
+
> u.email # => nil
|
33
|
+
|
34
|
+
> u.email = 'bob@orionet.ru'
|
35
|
+
> u.email # => 'bob@orionet.ru'
|
36
|
+
> u.emails # => ['bob@orionet.ru']
|
37
|
+
|
38
|
+
> u.email = 'john@orionet.ru'
|
39
|
+
> u.email # => 'john@orionet.ru'
|
40
|
+
> u.emails # => ['john@orionet.ru']
|
41
|
+
|
42
|
+
> u.add_email 'bob@orionet.ru'
|
43
|
+
> u.email # => 'john@orionet.ru'
|
44
|
+
> u.emails # => ['john@orionet.ru', 'bob@orionet.ru']
|
45
|
+
|
46
|
+
> u.email = 'bob@orionet.ru'
|
47
|
+
> u.email # => 'bob@orionet.ru'
|
48
|
+
> u.emails # => ['bob@orionet.ru', 'john@orionet.ru' ]
|
49
|
+
|
50
|
+
== Note on Patches/Pull Requests
|
51
|
+
|
52
|
+
* Fork the project.
|
53
|
+
* Make your feature addition or bug fix.
|
54
|
+
* Add tests for it. This is important so I don't break it in a
|
55
|
+
future version unintentionally.
|
56
|
+
* Commit, do not mess with rakefile, version, or history.
|
57
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
58
|
+
* Send me a pull request. Bonus points for topic branches.
|
59
|
+
|
60
|
+
== Copyright
|
61
|
+
|
62
|
+
Copyright (c) 2010 Danil Pismenny. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'jeweler'
|
9
|
+
Jeweler::Tasks.new do |gem|
|
10
|
+
gem.name = "has_many_emails"
|
11
|
+
gem.summary = %Q{Add multiply emails features to models like User without changing common behaviour of the email attribute}
|
12
|
+
gem.description = %Q{Add multiply emails features to models like User without changing common behaviour of the email attribute}
|
13
|
+
gem.email = "danil@orionet.ru"
|
14
|
+
gem.homepage = "http://github.com/dapi/has_many_emails"
|
15
|
+
gem.authors = ["Danil Pismenny"]
|
16
|
+
gem.add_development_dependency 'attribute_normalizer', ">= 0"
|
17
|
+
gem.add_development_dependency 'validate_email', ">= 0"
|
18
|
+
|
19
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
|
+
end
|
21
|
+
Jeweler::GemcutterTasks.new
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
desc 'Default: run specs.'
|
28
|
+
task :default => :spec
|
29
|
+
#task :default => :test
|
30
|
+
|
31
|
+
desc 'Run the specs'
|
32
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
33
|
+
t.rspec_opts = ['-d --colour --format progress']
|
34
|
+
# t.files = FileList['spec/**/*_spec.rb']
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'rake/testtask'
|
38
|
+
Rake::TestTask.new(:test) do |test|
|
39
|
+
test.libs << 'lib' << 'test'
|
40
|
+
test.pattern = 'test/**/test_*.rb'
|
41
|
+
test.verbose = true
|
42
|
+
end
|
43
|
+
|
44
|
+
begin
|
45
|
+
require 'rcov/rcovtask'
|
46
|
+
Rcov::RcovTask.new do |test|
|
47
|
+
test.libs << 'test'
|
48
|
+
test.pattern = 'test/**/test_*.rb'
|
49
|
+
test.verbose = true
|
50
|
+
end
|
51
|
+
rescue LoadError
|
52
|
+
task :rcov do
|
53
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
task :test => :check_dependencies
|
58
|
+
|
59
|
+
require 'rake/rdoctask'
|
60
|
+
Rake::RDocTask.new do |rdoc|
|
61
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
62
|
+
|
63
|
+
rdoc.rdoc_dir = 'rdoc'
|
64
|
+
rdoc.title = "has_many_emails #{version}"
|
65
|
+
rdoc.rdoc_files.include('README*')
|
66
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
67
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class EmailAddress < ActiveRecord::Base
|
3
|
+
belongs_to :user
|
4
|
+
|
5
|
+
normalize_attributes :email
|
6
|
+
|
7
|
+
validate :downcase_email # Опустим мыло даже у не сохраненных записей
|
8
|
+
|
9
|
+
# validates :user_id, :presence=>true
|
10
|
+
|
11
|
+
validates :email, :presence=>true, :email=>true, :uniqueness=>{ :case_sensitive=>false } #, :email #=>{ :allow_blank=>false, :allow_nil=>false }
|
12
|
+
|
13
|
+
#scope :main, where(:is_main=>true)
|
14
|
+
# scope :by_user, lambda { |user_id| where( :user_id=>user_id) }
|
15
|
+
|
16
|
+
# default_scope order( "is_main desc", :created_at )
|
17
|
+
# TODO переделать работу с is_main
|
18
|
+
|
19
|
+
# before_create :set_main
|
20
|
+
# after_save :reset_mains
|
21
|
+
|
22
|
+
def self.find_by_email(email)
|
23
|
+
super email.downcase
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
email
|
28
|
+
end
|
29
|
+
|
30
|
+
# TODO А в String кто пропишет такое-же?
|
31
|
+
def ==( email )
|
32
|
+
email.is_a?( String ) ? to_s==email : super(email)
|
33
|
+
end
|
34
|
+
|
35
|
+
# def set_main
|
36
|
+
# self.is_main = true if self.class.by_user( self.user_id ).empty?
|
37
|
+
# self.email.downcase!
|
38
|
+
# end
|
39
|
+
|
40
|
+
def downcase_email
|
41
|
+
self.email = email.downcase if email?
|
42
|
+
end
|
43
|
+
|
44
|
+
# def reset_mains
|
45
|
+
# self.class.update_all({ :is_main=>false, :user_id=>user_id },
|
46
|
+
# [ "id<>?", id ]) if is_main
|
47
|
+
# end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{has_many_emails}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Danil Pismenny"]
|
12
|
+
s.date = %q{2010-10-20}
|
13
|
+
s.description = %q{Add multiply emails features to models like User without changing common behaviour of the email attribute}
|
14
|
+
s.email = %q{danil@orionet.ru}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"MIT-LICENSE",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"app/models/email_address.rb",
|
25
|
+
"has_many_emails.gemspec",
|
26
|
+
"init.rb",
|
27
|
+
"lib/generators/USAGE",
|
28
|
+
"lib/generators/has_many_emails_generator.rb",
|
29
|
+
"lib/generators/templates/create_email_address.rb",
|
30
|
+
"lib/has_many_emails.rb",
|
31
|
+
"lib/has_many_emails/class_methods.rb",
|
32
|
+
"lib/has_many_emails/instance_methods.rb",
|
33
|
+
"rails/init.rb",
|
34
|
+
"spec/db/create_db.rb",
|
35
|
+
"spec/db/database.yml",
|
36
|
+
"spec/db/models/user.rb",
|
37
|
+
"spec/debug.log",
|
38
|
+
"spec/factories.rb",
|
39
|
+
"spec/models/email_spec.rb",
|
40
|
+
"spec/models/exampels_spec.rb",
|
41
|
+
"spec/models/user_emails_spec.rb",
|
42
|
+
"spec/models/user_spec.rb",
|
43
|
+
"spec/spec_helper.rb",
|
44
|
+
"test/helper.rb",
|
45
|
+
"test/test_has_many_emails.rb"
|
46
|
+
]
|
47
|
+
s.homepage = %q{http://github.com/dapi/has_many_emails}
|
48
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
49
|
+
s.require_paths = ["lib"]
|
50
|
+
s.rubygems_version = %q{1.3.7}
|
51
|
+
s.summary = %q{Add multiply emails features to models like User without changing common behaviour of the email attribute}
|
52
|
+
s.test_files = [
|
53
|
+
"spec/factories.rb",
|
54
|
+
"spec/models/exampels_spec.rb",
|
55
|
+
"spec/models/user_emails_spec.rb",
|
56
|
+
"spec/models/email_spec.rb",
|
57
|
+
"spec/models/user_spec.rb",
|
58
|
+
"spec/db/models/user.rb",
|
59
|
+
"spec/db/create_db.rb",
|
60
|
+
"spec/spec_helper.rb",
|
61
|
+
"test/helper.rb",
|
62
|
+
"test/test_has_many_emails.rb"
|
63
|
+
]
|
64
|
+
|
65
|
+
if s.respond_to? :specification_version then
|
66
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
67
|
+
s.specification_version = 3
|
68
|
+
|
69
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
70
|
+
s.add_development_dependency(%q<attribute_normalizer>, [">= 0"])
|
71
|
+
s.add_development_dependency(%q<validate_email>, [">= 0"])
|
72
|
+
else
|
73
|
+
s.add_dependency(%q<attribute_normalizer>, [">= 0"])
|
74
|
+
s.add_dependency(%q<validate_email>, [">= 0"])
|
75
|
+
end
|
76
|
+
else
|
77
|
+
s.add_dependency(%q<attribute_normalizer>, [">= 0"])
|
78
|
+
s.add_dependency(%q<validate_email>, [">= 0"])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/rails/init"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
|
3
|
+
|
4
|
+
class HasManyEmailsGenerator < Rails::Generators::Base
|
5
|
+
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
|
10
|
+
class_option :email_address_class_name, :default => 'EmailAddress', :aliases=>'-e'
|
11
|
+
class_option :models_with_emails, :default => ['User'], :type=>:array, :aliases=>'-m'
|
12
|
+
|
13
|
+
def self.next_migration_number(path)
|
14
|
+
Time.now.utc.to_s(:number)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_migration
|
18
|
+
migration_template 'create_email_address.rb', "db/migrate/create_#{email_address_table_name}.rb"
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def migration_name
|
24
|
+
"Create#{options[:email_address_class_name].pluralize}"
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def models_with_emails
|
29
|
+
options[:models_with_emails]
|
30
|
+
end
|
31
|
+
|
32
|
+
def email_address_table_name
|
33
|
+
options[:email_address_class_name].tableize
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class <%= migration_name %> < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
create_table :<%= email_address_table_name %> do |t|
|
5
|
+
t.integer :user_id, :null => false
|
6
|
+
t.string :email, :null => false
|
7
|
+
t.boolean :is_main, :null => false, :default=>false
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :<%= email_address_table_name %>, [:user_id, :email], :unique=>true
|
13
|
+
add_index :<%= email_address_table_name %>, :email
|
14
|
+
|
15
|
+
|
16
|
+
<% models_with_emails.each do |model| %>
|
17
|
+
if <%= model %>.column_names.include? 'email'
|
18
|
+
raise "PROBLEM! <%= model %> does not have 'has_many_emails'. Insert it before usage." unless <%= model %>.respond_to? :has_many_emails
|
19
|
+
<%= model %>.all.each do |user|
|
20
|
+
user.add_email user.attributes['email']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.down
|
28
|
+
|
29
|
+
drop_table :<%= email_address_table_name %>
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
require 'attribute_normalizer'
|
3
|
+
require 'validate_email'
|
4
|
+
|
5
|
+
require 'has_many_emails/class_methods'
|
6
|
+
require 'has_many_emails/instance_methods'
|
7
|
+
|
8
|
+
module HasManyEmails
|
9
|
+
|
10
|
+
# def has_many_emails(attribute_name, attribute_model_name)
|
11
|
+
def has_many_emails
|
12
|
+
class_eval <<-EOV
|
13
|
+
|
14
|
+
has_many :email_addresses, :dependent=>:destroy
|
15
|
+
|
16
|
+
validate :validate_email_addresses
|
17
|
+
|
18
|
+
EOV
|
19
|
+
|
20
|
+
extend HasManyEmails::ClassMethods
|
21
|
+
include HasManyEmails::InstanceMethods
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module HasManyEmails
|
4
|
+
module InstanceMethods
|
5
|
+
|
6
|
+
# def emails_uniqueness
|
7
|
+
# # TODO Нормальный перевод
|
8
|
+
# errors.add( :email, "Пользователь с таким емайлом уже зарегистрирован" ) if
|
9
|
+
# EmailAddress.find_by_email( email )
|
10
|
+
# end
|
11
|
+
def validate_email_addresses
|
12
|
+
email_addresses.each do |email_address|
|
13
|
+
if !email_address.valid? && email_address.errors.has_key?(:email)
|
14
|
+
email_address.errors[:email].each do |msg|
|
15
|
+
errors.add( :email, msg )
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_email?( value )
|
22
|
+
emails.include?( value.downcase )
|
23
|
+
end
|
24
|
+
|
25
|
+
# alias_method :email?, :has_email?
|
26
|
+
|
27
|
+
def email=( value )
|
28
|
+
super reset_email( value )
|
29
|
+
end
|
30
|
+
|
31
|
+
def reset_email( value )
|
32
|
+
if value.blank?
|
33
|
+
remove_email email if email?
|
34
|
+
elsif email? && email_address = find_email_address( email )
|
35
|
+
value.downcase!
|
36
|
+
return value if value==email
|
37
|
+
if new_email_address = find_email_address( value )
|
38
|
+
email_addresses.delete( email_address )
|
39
|
+
else
|
40
|
+
email_address.update_attribute( :email, value )
|
41
|
+
end
|
42
|
+
else
|
43
|
+
value.downcase!
|
44
|
+
add_email value
|
45
|
+
end
|
46
|
+
value
|
47
|
+
end
|
48
|
+
|
49
|
+
def emails
|
50
|
+
email_addresses.map(&:email)
|
51
|
+
end
|
52
|
+
|
53
|
+
def remove_email( value )
|
54
|
+
value.downcase!
|
55
|
+
email_address = find_email_address( value ) and email_addresses.delete( email_address )
|
56
|
+
email = nil if value==email
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_email( value )
|
60
|
+
value = value.email if value.is_a? EmailAddress
|
61
|
+
value.downcase!
|
62
|
+
return nil if value.blank? || has_email?( value )
|
63
|
+
|
64
|
+
h = { :email=>value }
|
65
|
+
|
66
|
+
if new_record?
|
67
|
+
email_addresses.build(:email=>value)
|
68
|
+
else
|
69
|
+
email_addresses.create(:email=>value)
|
70
|
+
email_addresses.reload
|
71
|
+
end
|
72
|
+
value
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_email_address( value )
|
76
|
+
value.downcase!
|
77
|
+
if new_record?
|
78
|
+
email_addresses.each { |ea|
|
79
|
+
return ea if ea.email==value
|
80
|
+
}
|
81
|
+
else
|
82
|
+
email_addresses.find_by_email value
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
def connection
|
4
|
+
ActiveRecord::Base.connection
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
# Establish connection
|
9
|
+
#unless ActiveRecord::Base.connected?
|
10
|
+
config = YAML::load(File.open("#{SPEC}/db/database.yml"))
|
11
|
+
ActiveRecord::Base.configurations = config
|
12
|
+
ActiveRecord::Base.establish_connection(config['test'])
|
13
|
+
#end
|
14
|
+
|
15
|
+
# Establish logger
|
16
|
+
# logger_file = File.open("#{SPEC}/db/log/test.log", 'a')
|
17
|
+
# logger_file.sync = true
|
18
|
+
# @logger = Logger.new(logger_file)
|
19
|
+
# ActiveRecord::Base.logger = @logger
|
20
|
+
|
21
|
+
# The database should have only a simple articles table
|
22
|
+
connection.execute("DROP TABLE IF EXISTS users")
|
23
|
+
connection.execute("DROP TABLE IF EXISTS email_addresses")
|
24
|
+
|
25
|
+
connection.create_table(:users) do |t|
|
26
|
+
t.string :name
|
27
|
+
t.string :email
|
28
|
+
t.timestamps
|
29
|
+
end
|
30
|
+
connection.create_table(:email_addresses) do |t|
|
31
|
+
t.string :email
|
32
|
+
# t.boolean :is_main
|
33
|
+
t.integer :user_id
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
|
37
|
+
connection.add_index :email_addresses, [:user_id, :email], :unique=>true
|
38
|
+
|
39
|
+
|
40
|
+
|
data/spec/debug.log
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Logfile created on Mon Oct 18 21:29:57 +0400 2010 by logger.rb/22285
|
data/spec/factories.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe EmailAddress do
|
5
|
+
|
6
|
+
#fixtures :users
|
7
|
+
|
8
|
+
it { should normalize_attribute(:email) }
|
9
|
+
|
10
|
+
should_validate_presence_of :email
|
11
|
+
# should_validate_presence_of :user_id
|
12
|
+
|
13
|
+
specify {
|
14
|
+
ea = EmailAddress.new( :email=>'danil@orionet.ru', :user_id=>1)
|
15
|
+
ea.should be_valid
|
16
|
+
}
|
17
|
+
|
18
|
+
before do
|
19
|
+
EmailAddress.destroy_all
|
20
|
+
end
|
21
|
+
|
22
|
+
context "normalize and downcase an email" do
|
23
|
+
before { @ea = EmailAddress.create( :email=>' DANIL@orionet.ru ', :user_id=>1) }
|
24
|
+
subject { @ea }
|
25
|
+
|
26
|
+
it { should be_valid }
|
27
|
+
specify { @ea.email.should == 'danil@orionet.ru' }
|
28
|
+
it { should == EmailAddress.find_by_email('DaNiL@orionet.ru') }
|
29
|
+
end
|
30
|
+
|
31
|
+
specify {
|
32
|
+
ea = EmailAddress.new( :email=>'danil.orionet.ru')
|
33
|
+
ea.should_not be_valid
|
34
|
+
|
35
|
+
ea = EmailAddress.new()
|
36
|
+
ea.should_not be_valid
|
37
|
+
|
38
|
+
ea = EmailAddress.new( :user_id=>1 )
|
39
|
+
ea.should_not be_valid
|
40
|
+
}
|
41
|
+
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "User's examples" do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
User.destroy_all
|
7
|
+
User.create!(:email=>EMAIL)
|
8
|
+
@user = User.new
|
9
|
+
end
|
10
|
+
|
11
|
+
subject { @user }
|
12
|
+
|
13
|
+
shared_examples_for "invalid user without EMAIL" do
|
14
|
+
it { should_not be_valid }
|
15
|
+
# it { should_not have_email(EMAIL)}
|
16
|
+
#specify { @user.emails.should be_empty }
|
17
|
+
# specify { @user.email.should be_nil }
|
18
|
+
specify { @user.errors[:email].should include("has already been taken") }
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
context "with existen email when create" do
|
23
|
+
before(:all) { @user = User.create(:email=>EMAIL) }
|
24
|
+
it_should_behave_like "invalid user without EMAIL"
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with existen email when set" do
|
28
|
+
before(:all) { @user.email=EMAIL }
|
29
|
+
it_should_behave_like "invalid user without EMAIL"
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with existen email when add" do
|
33
|
+
before(:all) { @user.add_email EMAIL }
|
34
|
+
it_should_behave_like "invalid user without EMAIL"
|
35
|
+
end
|
36
|
+
|
37
|
+
context "with an email " do
|
38
|
+
before(:all) { @user = User.new(:email=>EMAIL1) }
|
39
|
+
it { should be_valid }
|
40
|
+
it { should have_email(EMAIL1)}
|
41
|
+
|
42
|
+
context "add existen email" do
|
43
|
+
before(:all) { @user.add_email EMAIL }
|
44
|
+
it { should_not be_valid }
|
45
|
+
it { should have_email(EMAIL1)}
|
46
|
+
specify { @user.emails.count.should == 2 }
|
47
|
+
specify { @user.errors[:email].should include("has already been taken") }
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe "User have many emails" do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
User.destroy_all
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { @user }
|
11
|
+
|
12
|
+
shared_examples_for "valid user with one EMAIL" do
|
13
|
+
it { should be_valid }
|
14
|
+
it { should have_email(EMAIL)}
|
15
|
+
specify { @user.emails.count.should == 1 }
|
16
|
+
specify { @user.email.should == EMAIL }
|
17
|
+
end
|
18
|
+
|
19
|
+
shared_examples_for "valid user with EMAIL and EMAIL2" do
|
20
|
+
it { should have_email(EMAIL)}
|
21
|
+
it { should have_email(EMAIL2)}
|
22
|
+
specify { @user.emails.count.should == 2 }
|
23
|
+
specify { @user.email.should == EMAIL }
|
24
|
+
end
|
25
|
+
|
26
|
+
shared_examples_for "valid user with one EMAIL2" do
|
27
|
+
it { should_not have_email(EMAIL)}
|
28
|
+
it { should have_email(EMAIL2)}
|
29
|
+
specify { @user.emails.count.should == 1 }
|
30
|
+
specify { @user.email.should == EMAIL2 }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "new_record" do
|
34
|
+
|
35
|
+
before(:all) { @user = User.new(:email=>EMAIL) }
|
36
|
+
it_should_behave_like "valid user with one EMAIL"
|
37
|
+
|
38
|
+
context "add second email" do
|
39
|
+
|
40
|
+
before(:all) { @user.add_email EMAIL2 }
|
41
|
+
it_should_behave_like "valid user with EMAIL and EMAIL2"
|
42
|
+
|
43
|
+
context "reset remail" do
|
44
|
+
before(:all) { @user.email=EMAIL2 }
|
45
|
+
it_should_behave_like "valid user with one EMAIL2"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "created record" do
|
52
|
+
|
53
|
+
before(:all) { @user = User.create!(:email=>EMAIL) }
|
54
|
+
it_should_behave_like "valid user with one EMAIL"
|
55
|
+
|
56
|
+
context "add second email" do
|
57
|
+
|
58
|
+
before(:all) { @user.add_email EMAIL2 }
|
59
|
+
it_should_behave_like "valid user with EMAIL and EMAIL2"
|
60
|
+
|
61
|
+
context "reset remail" do
|
62
|
+
before(:all) { @user.email=EMAIL2 }
|
63
|
+
it_should_behave_like "valid user with one EMAIL2"
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe User do
|
5
|
+
|
6
|
+
it { should.respond_to? :has_many_email? }
|
7
|
+
it { should normalize_attribute(:email) }
|
8
|
+
|
9
|
+
context "user record" do
|
10
|
+
|
11
|
+
shared_examples_for "valid" do
|
12
|
+
it { should be_a User}
|
13
|
+
it { should be_valid }
|
14
|
+
it { should be_email }
|
15
|
+
specify { @user.emails.count.should == 1 }
|
16
|
+
|
17
|
+
specify "blank email" do
|
18
|
+
@user.email = ''
|
19
|
+
@user.emails.should be_empty
|
20
|
+
@user.email.should be_nil
|
21
|
+
end
|
22
|
+
specify "nil email" do
|
23
|
+
@user.email = nil
|
24
|
+
@user.emails.should be_empty
|
25
|
+
@user.email.should be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
shared_examples_for "valid and have an email" do
|
31
|
+
it { should have_email(EMAIL)}
|
32
|
+
specify { @user.email.should == EMAIL }
|
33
|
+
|
34
|
+
it_should_behave_like "valid"
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
subject { @user }
|
39
|
+
|
40
|
+
context "New user" do
|
41
|
+
before(:all) do
|
42
|
+
@user = User.new
|
43
|
+
end
|
44
|
+
|
45
|
+
it { should be_new_record }
|
46
|
+
|
47
|
+
it { should be_valid }
|
48
|
+
it { should_not have_email(EMAIL) }
|
49
|
+
|
50
|
+
specify { @user.email.should be_nil}
|
51
|
+
specify { @user.emails.should be_empty}
|
52
|
+
|
53
|
+
|
54
|
+
context "initialized with an email" do
|
55
|
+
before(:all) { @user = User.new(:email=>EMAIL) }
|
56
|
+
it_should_behave_like "valid and have an email"
|
57
|
+
context "reset email" do
|
58
|
+
before(:all) { @user.email=EMAIL }
|
59
|
+
it_should_behave_like "valid and have an email"
|
60
|
+
end
|
61
|
+
context "reset email to EMAIL2" do
|
62
|
+
before(:all) { @user.email=EMAIL2 }
|
63
|
+
it { should have_email(EMAIL2) }
|
64
|
+
specify { @user.email.should == EMAIL2 }
|
65
|
+
it_should_behave_like "valid"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with set email" do
|
70
|
+
before(:all) { @user.email=EMAIL }
|
71
|
+
it_should_behave_like "valid and have an email"
|
72
|
+
end
|
73
|
+
|
74
|
+
context "update_attribute" do
|
75
|
+
before(:all) { @user.update_attribute(:email, EMAIL) }
|
76
|
+
it_should_behave_like "valid and have an email"
|
77
|
+
end
|
78
|
+
|
79
|
+
context "update_attributes" do
|
80
|
+
before(:all) { @user.update_attributes({:email=>EMAIL}) }
|
81
|
+
it_should_behave_like "valid and have an email"
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
context "Saved user" do
|
88
|
+
before(:all) do
|
89
|
+
@user = User.create!
|
90
|
+
end
|
91
|
+
|
92
|
+
it { should_not be_new_record }
|
93
|
+
|
94
|
+
it { should be_valid }
|
95
|
+
it { should_not have_email(EMAIL) }
|
96
|
+
|
97
|
+
specify { @user.email.should be_nil}
|
98
|
+
specify { @user.emails.should be_empty}
|
99
|
+
|
100
|
+
context "with set email" do
|
101
|
+
before(:all) { @user.email=EMAIL }
|
102
|
+
it_should_behave_like "valid and have an email"
|
103
|
+
end
|
104
|
+
|
105
|
+
context "initialized with an email" do
|
106
|
+
before(:all) { @user = User.create!(:email=>EMAIL) }
|
107
|
+
it_should_behave_like "valid and have an email"
|
108
|
+
|
109
|
+
context "and unset email" do
|
110
|
+
before(:all) { @user.email = '' }
|
111
|
+
specify { @user.emails.should be_empty }
|
112
|
+
specify { @user.email.should be_nil }
|
113
|
+
end
|
114
|
+
|
115
|
+
context "that removes email" do
|
116
|
+
before(:all) { @user.remove_email EMAIL }
|
117
|
+
specify { @user.emails.should be_empty }
|
118
|
+
specify { @user.email.should be_nil }
|
119
|
+
end
|
120
|
+
|
121
|
+
# specify "remove_email" do
|
122
|
+
# debugger
|
123
|
+
# @user.remove_email EMAIL
|
124
|
+
# @user.emails.should be_empty
|
125
|
+
# @user.email.should be_nil
|
126
|
+
# end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "update_attribute" do
|
130
|
+
before(:all) { @user.update_attribute(:email, EMAIL) }
|
131
|
+
it_should_behave_like "valid and have an email"
|
132
|
+
end
|
133
|
+
|
134
|
+
context "update_attributes" do
|
135
|
+
before(:all) { @user.update_attributes({:email=>EMAIL}) }
|
136
|
+
it_should_behave_like "valid and have an email"
|
137
|
+
end
|
138
|
+
|
139
|
+
context "update_attribute" do
|
140
|
+
before(:all) { @user.update_attribute(:email, EMAIL) }
|
141
|
+
it_should_behave_like "valid and have an email"
|
142
|
+
end
|
143
|
+
|
144
|
+
context "update_attributes" do
|
145
|
+
before(:all) { @user.update_attributes({:email=>EMAIL}) }
|
146
|
+
it_should_behave_like "valid and have an email"
|
147
|
+
end
|
148
|
+
|
149
|
+
context "reset attribute to EMAIL2" do
|
150
|
+
before(:all) { @user.email=EMAIL2 }
|
151
|
+
it { should have_email(EMAIL2) }
|
152
|
+
specify { @user.email.should == EMAIL2 }
|
153
|
+
it_should_behave_like "valid"
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
context "update_attribute to EMAIL2" do
|
158
|
+
before(:all) { @user.update_attribute(:email, EMAIL2) }
|
159
|
+
it { should have_email(EMAIL2) }
|
160
|
+
specify { @user.email.should == EMAIL2 }
|
161
|
+
it_should_behave_like "valid"
|
162
|
+
end
|
163
|
+
|
164
|
+
context "update_attributes to EMAIL2" do
|
165
|
+
before(:all) { @user.update_attributes({:email=>EMAIL2}) }
|
166
|
+
it { should have_email(EMAIL2) }
|
167
|
+
specify { @user.email.should == EMAIL2 }
|
168
|
+
it_should_behave_like "valid"
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'active_record'
|
4
|
+
require 'remarkable/active_record'
|
5
|
+
|
6
|
+
require 'rails/init'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.include AttributeNormalizer::RSpecMatcher # Models group type is missing at this time rspec-rails 2.0.0.beta.11
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
SPEC='./spec'
|
14
|
+
|
15
|
+
# Create database and connection
|
16
|
+
require 'db/create_db'
|
17
|
+
|
18
|
+
# Load the model
|
19
|
+
load "#{SPEC}/../app/models/email_address.rb"
|
20
|
+
load "#{SPEC}/db/models/user.rb"
|
21
|
+
|
22
|
+
|
23
|
+
# require 'factory_girl'
|
24
|
+
#require File.dirname(__FILE__) + "/factories"
|
25
|
+
|
26
|
+
|
27
|
+
EMAIL='bob@orionet.ru'
|
28
|
+
EMAIL1='bob1@orionet.ru'
|
29
|
+
EMAIL2='bob2@orionet.ru'
|
30
|
+
EMAIL3='bob3@orionet.ru'
|
data/test/helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: has_many_emails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Danil Pismenny
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-20 00:00:00 +04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: attribute_normalizer
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: validate_email
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
description: Add multiply emails features to models like User without changing common behaviour of the email attribute
|
50
|
+
email: danil@orionet.ru
|
51
|
+
executables: []
|
52
|
+
|
53
|
+
extensions: []
|
54
|
+
|
55
|
+
extra_rdoc_files:
|
56
|
+
- README.rdoc
|
57
|
+
files:
|
58
|
+
- .gitignore
|
59
|
+
- MIT-LICENSE
|
60
|
+
- README.rdoc
|
61
|
+
- Rakefile
|
62
|
+
- VERSION
|
63
|
+
- app/models/email_address.rb
|
64
|
+
- has_many_emails.gemspec
|
65
|
+
- init.rb
|
66
|
+
- lib/generators/USAGE
|
67
|
+
- lib/generators/has_many_emails_generator.rb
|
68
|
+
- lib/generators/templates/create_email_address.rb
|
69
|
+
- lib/has_many_emails.rb
|
70
|
+
- lib/has_many_emails/class_methods.rb
|
71
|
+
- lib/has_many_emails/instance_methods.rb
|
72
|
+
- rails/init.rb
|
73
|
+
- spec/db/create_db.rb
|
74
|
+
- spec/db/database.yml
|
75
|
+
- spec/db/models/user.rb
|
76
|
+
- spec/debug.log
|
77
|
+
- spec/factories.rb
|
78
|
+
- spec/models/email_spec.rb
|
79
|
+
- spec/models/exampels_spec.rb
|
80
|
+
- spec/models/user_emails_spec.rb
|
81
|
+
- spec/models/user_spec.rb
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
- test/helper.rb
|
84
|
+
- test/test_has_many_emails.rb
|
85
|
+
has_rdoc: true
|
86
|
+
homepage: http://github.com/dapi/has_many_emails
|
87
|
+
licenses: []
|
88
|
+
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options:
|
91
|
+
- --charset=UTF-8
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
hash: 3
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
version: "0"
|
112
|
+
requirements: []
|
113
|
+
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.3.7
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: Add multiply emails features to models like User without changing common behaviour of the email attribute
|
119
|
+
test_files:
|
120
|
+
- spec/factories.rb
|
121
|
+
- spec/models/exampels_spec.rb
|
122
|
+
- spec/models/user_emails_spec.rb
|
123
|
+
- spec/models/email_spec.rb
|
124
|
+
- spec/models/user_spec.rb
|
125
|
+
- spec/db/models/user.rb
|
126
|
+
- spec/db/create_db.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- test/helper.rb
|
129
|
+
- test/test_has_many_emails.rb
|