mongoid-verbalize 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/LICENSE +0 -0
- data/README.md +0 -0
- data/Rakefile +25 -0
- data/lib/mongoid/verbalize.rb +36 -0
- data/lib/mongoid/verbalize/fields.rb +75 -0
- data/lib/mongoid/verbalize/selector.rb +14 -0
- data/lib/mongoid/verbalize/translated_string.rb +137 -0
- data/lib/mongoid/verbalize/verbalized_validator.rb +27 -0
- data/lib/mongoid/verbalize/verbalized_version.rb +7 -0
- data/lib/mongoid/verbalize/versioning.rb +85 -0
- data/spec/mongoid/verbalize_spec.rb +600 -0
- data/spec/spec_helper.rb +22 -0
- metadata +153 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE
ADDED
File without changes
|
data/README.md
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
require 'yard'
|
3
|
+
|
4
|
+
spec = Gem::Specification.load("mongoid-verbalize.gemspec")
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
|
8
|
+
task :default => :spec
|
9
|
+
|
10
|
+
YARD::Rake::YardocTask.new(:doc)
|
11
|
+
|
12
|
+
desc "Build the .gem file"
|
13
|
+
task :build do
|
14
|
+
system "gem build #{spec.name}.gemspec"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Push the .gem file to rubygems.org"
|
18
|
+
task :release => :build do
|
19
|
+
system "gem push #{spec.name}-#{spec.version}.gem"
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Open an irb session"
|
23
|
+
task :console do
|
24
|
+
sh "irb -rubygems -I lib -r ./spec/spec_helper.rb"
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'mongoid/verbalize/fields'
|
2
|
+
require 'mongoid/verbalize/translated_string'
|
3
|
+
require 'mongoid/verbalize/selector'
|
4
|
+
require 'mongoid/verbalize/verbalized_validator'
|
5
|
+
require 'mongoid/verbalize/verbalized_version'
|
6
|
+
require 'mongoid/verbalize/versioning'
|
7
|
+
|
8
|
+
module Mongoid
|
9
|
+
module Verbalize
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
include Mongoid::Verbalize::Fields
|
14
|
+
|
15
|
+
Mongoid::Fields.option :use_default_if_empty do |model, field, value| end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def verbalized_field(name, options = {})
|
20
|
+
field(name, options.merge(:type => TranslatedString, :default => {}))
|
21
|
+
end
|
22
|
+
|
23
|
+
def validates_default_locale(names, options = {})
|
24
|
+
validates_with VerbalizedValidator, options.merge(:mode => :only_default, :attributes => names)
|
25
|
+
end
|
26
|
+
|
27
|
+
def validates_one_locale(names, options = {})
|
28
|
+
validates_with VerbalizedValidator, options.merge(:mode => :one_locale, :attributes => names)
|
29
|
+
end
|
30
|
+
|
31
|
+
def validates_all_locales(names, options = {})
|
32
|
+
validates_with VerbalizedValidator, options.merge(:mode => :all_locales, :attributes => names)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Verbalize
|
3
|
+
module Fields
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
# Monkey patch for Mongoid method
|
11
|
+
def create_accessors(name, meth, options = {})
|
12
|
+
# Let Mongoid do its thing
|
13
|
+
super
|
14
|
+
|
15
|
+
return unless options[:type] == Mongoid::Verbalize::TranslatedString
|
16
|
+
|
17
|
+
field = fields[name]
|
18
|
+
|
19
|
+
create_verbalized_field_getter(name, meth, field)
|
20
|
+
create_verbalized_field_setter(name, meth, field)
|
21
|
+
|
22
|
+
create_verbalized_translations_getter(name, meth, field)
|
23
|
+
|
24
|
+
create_verbalized_translations_raw_getter(name, meth)
|
25
|
+
create_verbalized_translations_raw_setter(name, meth)
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_verbalized_field_getter(name, meth, field)
|
29
|
+
generated_methods.module_eval do
|
30
|
+
define_method("#{meth}") do
|
31
|
+
raw = read_attribute(name)
|
32
|
+
field_value = field.demongoize(raw)
|
33
|
+
field_value.current_locale_value(field.options[:use_default_if_empty])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_verbalized_field_setter(name, meth, field)
|
39
|
+
generated_methods.module_eval do
|
40
|
+
define_method("#{meth}=") do |value|
|
41
|
+
raw = read_attribute(name)
|
42
|
+
field_value = field.demongoize(raw)
|
43
|
+
field_value.current_locale_value = value
|
44
|
+
write_attribute(name, field_value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_verbalized_translations_getter(name, meth, field)
|
50
|
+
generated_methods.module_eval do
|
51
|
+
define_method("#{meth}_translations") do
|
52
|
+
field.demongoize(read_attribute(name))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_verbalized_translations_raw_getter(name, meth)
|
58
|
+
generated_methods.module_eval do
|
59
|
+
define_method("#{meth}_translations_raw") do
|
60
|
+
read_attribute(name)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_verbalized_translations_raw_setter(name, meth)
|
66
|
+
generated_methods.module_eval do
|
67
|
+
define_method("#{meth}_translations_raw=") do |values|
|
68
|
+
write_attribute(name, values)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Verbalize
|
3
|
+
# Strongly-typed accessor for this structure:
|
4
|
+
# {
|
5
|
+
# 'en' => { "value" => "Title", "versions" => [ { "version" => 0, "value" => 'Title' } ] },
|
6
|
+
# 'es' => { "value" => "Título", "versions" => [ { "version" => 0, "value" => 'Título' } ] },
|
7
|
+
# }
|
8
|
+
class TranslatedString
|
9
|
+
class LocalizedValue
|
10
|
+
attr_accessor :current_value, :versions
|
11
|
+
|
12
|
+
def initialize(current_value=nil, versions=[])
|
13
|
+
@current_value = current_value
|
14
|
+
@versions = versions
|
15
|
+
end
|
16
|
+
|
17
|
+
def changed?
|
18
|
+
previous_version = versions.last
|
19
|
+
previous_version.nil? || previous_version.value != current_value
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_version(new_version_number)
|
23
|
+
versions.push(LocalizedVersion.new(new_version_number, current_value))
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_version(version)
|
27
|
+
versions.find_all { |v| v.version <= version }.last
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
LocalizedVersion = Struct.new(:version, :value)
|
32
|
+
|
33
|
+
attr_reader :localized_values
|
34
|
+
|
35
|
+
def initialize(localized_values)
|
36
|
+
@localized_values = localized_values
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_version(language, version)
|
40
|
+
localized_value = @localized_values[language]
|
41
|
+
return unless localized_value.present?
|
42
|
+
|
43
|
+
localized_value.find_version(version)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Return translated value of field, accoring to current locale.
|
47
|
+
# If :use_default_if_empty is set, then in case when there no
|
48
|
+
# translation available for current locale, if will try to
|
49
|
+
# get translation for defalt_locale.
|
50
|
+
def current_locale_value(use_default_if_empty)
|
51
|
+
lookups = [self.class.current_locale]
|
52
|
+
|
53
|
+
# TODO: Add I18n.fallbacks support instead of :use_default_if_empty
|
54
|
+
if use_default_if_empty
|
55
|
+
lookups.push(::I18n.default_locale)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Find first localized value in lookup path
|
59
|
+
localized_value = @localized_values[lookups.find { |l| @localized_values[l] }]
|
60
|
+
return nil if localized_value.nil?
|
61
|
+
|
62
|
+
localized_value.current_value
|
63
|
+
end
|
64
|
+
def current_locale_value=(value)
|
65
|
+
current_value.current_value = value
|
66
|
+
end
|
67
|
+
|
68
|
+
# Called when determining whether to create a new version.
|
69
|
+
def changed?
|
70
|
+
@localized_values.values.any?(&:changed?)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Creates a new version for changed values
|
74
|
+
def prepare_for_save(new_version_number)
|
75
|
+
@localized_values.values.select(&:changed?).each do |v|
|
76
|
+
v.add_version(new_version_number)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Converts an object of this instance into a database friendly value.
|
81
|
+
def mongoize
|
82
|
+
@localized_values.each_with_object({}) do |(key, value), h|
|
83
|
+
h[key.to_s] = {
|
84
|
+
'value' => value.current_value,
|
85
|
+
'versions' => value.versions.map do |v|
|
86
|
+
{ 'version' => v.version, 'value' => v.value }
|
87
|
+
end
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class << self
|
93
|
+
# Get the object as it was stored in the database, and instantiate
|
94
|
+
# this custom class from it.
|
95
|
+
def demongoize(object)
|
96
|
+
localized_values = object.each_with_object({}) do |(key, value), h|
|
97
|
+
versions = (value['versions'] || []).map do |v|
|
98
|
+
LocalizedVersion.new(v['version'], v['value'])
|
99
|
+
end
|
100
|
+
h[key.to_sym] = LocalizedValue.new(value['value'], versions)
|
101
|
+
end
|
102
|
+
TranslatedString.new(localized_values)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Takes any possible object and converts it to how it would be
|
106
|
+
# stored in the database.
|
107
|
+
def mongoize(object)
|
108
|
+
case object
|
109
|
+
when TranslatedString then object.mongoize
|
110
|
+
else object
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Converts the object that was supplied to a criteria and converts it
|
115
|
+
# into a database friendly form.
|
116
|
+
def evolve(object)
|
117
|
+
case object
|
118
|
+
when TranslatedString then object.mongoize.current_locale_value
|
119
|
+
else object
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Return current locale as string
|
124
|
+
def current_locale
|
125
|
+
::I18n.locale
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
# TODO: Rename this method.
|
132
|
+
def current_value
|
133
|
+
@localized_values[self.class.current_locale] ||= LocalizedValue.new
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Verbalize
|
3
|
+
class VerbalizedValidator < ActiveModel::EachValidator
|
4
|
+
def validate_each record, attribute, value
|
5
|
+
if options[:mode] == :only_default
|
6
|
+
if record.send("#{attribute}_translations_raw")[::I18n.default_locale.to_s].blank?
|
7
|
+
record.errors.add(attribute, :locale_blank, options.except(:mode).merge(
|
8
|
+
:cur_locale => ::I18n.t(:"locales.#{::I18n.default_locale}", :default => ::I18n.default_locale.to_s)
|
9
|
+
))
|
10
|
+
end
|
11
|
+
elsif options[:mode] == :one_locale
|
12
|
+
record.errors.add(attribute, :all_locales_blank, options.except(:mode)) if record.send("#{attribute}_translations_raw").empty?
|
13
|
+
elsif options[:mode] == :all_locales
|
14
|
+
#difference between available locales and stored locales
|
15
|
+
diffloc = ::I18n.available_locales - record.send("#{attribute}_translations_raw").keys.collect { |key| key.to_sym }
|
16
|
+
|
17
|
+
#print an error for each missing locale
|
18
|
+
diffloc.each do |locale|
|
19
|
+
record.errors.add(attribute, :locale_blank, options.except(:mode).merge(
|
20
|
+
:cur_locale => ::I18n.t(:"locales.#{locale}", :default => locale.to_s)
|
21
|
+
))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Verbalize
|
3
|
+
module Versioning
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include ActiveSupport::Callbacks
|
8
|
+
|
9
|
+
define_callbacks :create_version
|
10
|
+
embeds_many :verbalized_versions, :as => :versionable,
|
11
|
+
:class_name => 'Mongoid::Verbalize::VerbalizedVersion'
|
12
|
+
before_save :create_new_version
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def verbalized_fields(document)
|
17
|
+
document.class.fields.reject { |name, field| field.options[:type] != TranslatedString }
|
18
|
+
end
|
19
|
+
|
20
|
+
def verbalized_children(document)
|
21
|
+
document._children.reject { |child| !child.class.include?(Mongoid::Verbalize) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def verbalized_field_values(document)
|
25
|
+
verbalized_fields(document).map do |name, field|
|
26
|
+
document.send("#{field.name}_translations")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def iterate_verbalized_fields(document, &block)
|
31
|
+
verbalized_fields(document).each do |name, field|
|
32
|
+
yield document, field
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def create_new_version
|
40
|
+
return if embedded? # Only do this on the root document
|
41
|
+
|
42
|
+
# Do a first pass to see if any verbalized field has changed
|
43
|
+
any_field_changed = false
|
44
|
+
iterate_all_verbalized_fields do |document, field|
|
45
|
+
any_field_changed = true if field.demongoize(document.read_attribute(field.name)).changed?
|
46
|
+
end
|
47
|
+
return unless any_field_changed
|
48
|
+
|
49
|
+
run_callbacks :create_version do
|
50
|
+
# Calculate new version number
|
51
|
+
previous_version = self.verbalized_versions.last.version if self.verbalized_versions.last.present?
|
52
|
+
next_version_number = previous_version.present? ? previous_version + 1 : 0
|
53
|
+
self.verbalized_versions.build(:version => next_version_number)
|
54
|
+
|
55
|
+
# Apply this new version number to verbalized fields
|
56
|
+
iterate_all_verbalized_fields do |document, field|
|
57
|
+
field_value = field.demongoize(document.read_attribute(field.name))
|
58
|
+
field_value.prepare_for_save(next_version_number)
|
59
|
+
document.write_attribute(field.name, field_value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Reset _children so that Mongoid persists verbalized_versions correctly
|
64
|
+
@_children = nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def all_verbalized_field_values
|
68
|
+
[self.class.verbalized_field_values(self) + self.class.verbalized_children(self).map do |child|
|
69
|
+
self.class.verbalized_field_values(child)
|
70
|
+
end].flatten
|
71
|
+
end
|
72
|
+
|
73
|
+
def iterate_all_verbalized_fields(&block)
|
74
|
+
self.class.iterate_verbalized_fields(self, &block)
|
75
|
+
self.class.verbalized_children(self).each do |child|
|
76
|
+
self.class.iterate_verbalized_fields(child, &block)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def current_version
|
81
|
+
self.verbalized_versions.last.version
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,600 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
class Entry
|
5
|
+
include Mongoid::Document
|
6
|
+
include Mongoid::Verbalize
|
7
|
+
include Mongoid::Verbalize::Versioning
|
8
|
+
|
9
|
+
field :weight, :type => Integer, :default => 60
|
10
|
+
|
11
|
+
verbalized_field :title
|
12
|
+
verbalized_field :title_with_default, :use_default_if_empty => true
|
13
|
+
end
|
14
|
+
|
15
|
+
class EntryWithValidations
|
16
|
+
include Mongoid::Document
|
17
|
+
include Mongoid::Verbalize
|
18
|
+
include Mongoid::Verbalize::Versioning
|
19
|
+
|
20
|
+
verbalized_field :title_validated_with_default_locale
|
21
|
+
verbalized_field :title_validated_with_one_locale
|
22
|
+
verbalized_field :title_validated_with_all_locales
|
23
|
+
|
24
|
+
validates_default_locale :title_validated_with_default_locale
|
25
|
+
validates_one_locale :title_validated_with_one_locale
|
26
|
+
validates_all_locales :title_validated_with_all_locales
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Mongoid::Verbalize, "verbalized_field" do
|
30
|
+
before do
|
31
|
+
I18n.locale = :en
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "without an assigned value" do
|
35
|
+
before do
|
36
|
+
@entry = Entry.new
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return blank" do
|
40
|
+
@entry.title.should be_blank
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "with an assigned value" do
|
45
|
+
before do
|
46
|
+
@entry = Entry.new(:title => 'Title')
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return that value" do
|
50
|
+
@entry.title.should == 'Title'
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "and persisted" do
|
54
|
+
before do
|
55
|
+
@entry.save
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "find by id" do
|
59
|
+
it "should find the document" do
|
60
|
+
Entry.find(@entry.id).should == @entry
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "where() criteria" do
|
65
|
+
it "should use the current locale value" do
|
66
|
+
query = Entry.where(:title => 'Title')
|
67
|
+
Entry.where(:title => 'Title').first.should == @entry
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "when the locale is changed" do
|
73
|
+
before do
|
74
|
+
I18n.locale = :es
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should return a blank value" do
|
78
|
+
@entry.title.should be_blank
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "a new value is assigned" do
|
82
|
+
before do
|
83
|
+
@entry.title = 'Título'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should return the new value" do
|
87
|
+
@entry.title.should == 'Título'
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "persisted and retrieved from db" do
|
91
|
+
before do
|
92
|
+
@entry.save
|
93
|
+
@entry.reload
|
94
|
+
end
|
95
|
+
|
96
|
+
it "the localized field value should be correct" do
|
97
|
+
@entry.title.should == 'Título'
|
98
|
+
I18n.locale = :en
|
99
|
+
@entry.title.should == 'Title'
|
100
|
+
@entry.title_translations_raw.should == {
|
101
|
+
'en' => { "value" => "Title", "versions" => [ { "version" => 0, "value" => 'Title' } ] },
|
102
|
+
'es' => { "value" => "Título", "versions" => [ { "version" => 0, "value" => 'Título' } ] },
|
103
|
+
}
|
104
|
+
@entry.verbalized_versions.should have(1).item
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "field translations hash" do
|
109
|
+
context "before saving" do
|
110
|
+
it "should return all translations without versions" do
|
111
|
+
@entry.title_translations_raw.should == {
|
112
|
+
'en' => { "value" => "Title", "versions" => [] },
|
113
|
+
'es' => { "value" => "Título", "versions" => [] },
|
114
|
+
}
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "after saving" do
|
119
|
+
before do
|
120
|
+
@entry.save
|
121
|
+
@entry.reload
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should return all translations with versions" do
|
125
|
+
@entry.title_translations_raw.should == {
|
126
|
+
'en' => { "value" => "Title", "versions" => [ { "version" => 0, "value" => 'Title' } ] },
|
127
|
+
'es' => { "value" => "Título", "versions" => [ { "version" => 0, "value" => 'Título' } ] },
|
128
|
+
}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "field translations" do
|
134
|
+
context "before saving" do
|
135
|
+
it "should return all translations without versions" do
|
136
|
+
@entry.title_translations.should be_instance_of(
|
137
|
+
Mongoid::Verbalize::TranslatedString)
|
138
|
+
@entry.title_translations.localized_values[:en].should be_instance_of(
|
139
|
+
Mongoid::Verbalize::TranslatedString::LocalizedValue)
|
140
|
+
@entry.title_translations.localized_values[:en].current_value.should == 'Title'
|
141
|
+
@entry.title_translations.localized_values[:en].versions.should == []
|
142
|
+
@entry.title_translations.localized_values[:es].should be_instance_of(
|
143
|
+
Mongoid::Verbalize::TranslatedString::LocalizedValue)
|
144
|
+
@entry.title_translations.localized_values[:es].current_value.should == 'Título'
|
145
|
+
@entry.title_translations.localized_values[:es].versions.should == []
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "after saving" do
|
150
|
+
before do
|
151
|
+
@entry.save
|
152
|
+
@entry.reload
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should return all translations with versions" do
|
156
|
+
@entry.title_translations.localized_values[:en].should be_instance_of(
|
157
|
+
Mongoid::Verbalize::TranslatedString::LocalizedValue)
|
158
|
+
@entry.title_translations.localized_values[:en].current_value.should == 'Title'
|
159
|
+
@entry.title_translations.localized_values[:en].versions.should have(1).item
|
160
|
+
@entry.title_translations.localized_values[:en].versions[0].should be_instance_of(
|
161
|
+
Mongoid::Verbalize::TranslatedString::LocalizedVersion)
|
162
|
+
@entry.title_translations.localized_values[:en].versions[0].version.should == 0
|
163
|
+
@entry.title_translations.localized_values[:en].versions[0].value.should == 'Title'
|
164
|
+
@entry.title_translations.localized_values[:es].should be_instance_of(
|
165
|
+
Mongoid::Verbalize::TranslatedString::LocalizedValue)
|
166
|
+
@entry.title_translations.localized_values[:es].current_value.should == 'Título'
|
167
|
+
@entry.title_translations.localized_values[:es].versions.should have(1).item
|
168
|
+
@entry.title_translations.localized_values[:es].versions[0].should be_instance_of(
|
169
|
+
Mongoid::Verbalize::TranslatedString::LocalizedVersion)
|
170
|
+
@entry.title_translations.localized_values[:es].versions[0].version.should == 0
|
171
|
+
@entry.title_translations.localized_values[:es].versions[0].value.should == 'Título'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "with mass-assigned translations" do
|
177
|
+
before do
|
178
|
+
@entry.title_translations_raw = {
|
179
|
+
'en' => { "value" => "Title", "versions" => [ { "version" => 0, "value" => 'Title' } ] },
|
180
|
+
'es' => { "value" => "Nuevo título", "versions" => [ { "version" => 0, "value" => 'Nuevo título' } ] },
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should set all translations" do
|
185
|
+
@entry.title_translations_raw.should == {
|
186
|
+
'en' => { "value" => "Title", "versions" => [ { "version" => 0, "value" => 'Title' } ] },
|
187
|
+
'es' => { "value" => "Nuevo título", "versions" => [ { "version" => 0, "value" => 'Nuevo título' } ] },
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
it "the getter should return the new translation" do
|
192
|
+
@entry.title.should == 'Nuevo título'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "if we go back to the original locale" do
|
197
|
+
before do
|
198
|
+
I18n.locale = :en
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should return the original value" do
|
202
|
+
@entry.title.should == 'Title'
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe Mongoid::Verbalize do
|
211
|
+
before do
|
212
|
+
I18n.locale = :en
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "versions" do
|
216
|
+
before { @entry = Entry.new }
|
217
|
+
subject { @entry }
|
218
|
+
|
219
|
+
describe "document versions" do
|
220
|
+
before do
|
221
|
+
@entry.title = 'foo'
|
222
|
+
@entry.save
|
223
|
+
end
|
224
|
+
|
225
|
+
its(:verbalized_versions) { should have(1).item }
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "when field is updated twice without saving" do
|
229
|
+
before do
|
230
|
+
@entry.title = 'foo'
|
231
|
+
@entry.title = 'bar'
|
232
|
+
@expected_translations = {
|
233
|
+
'en' => { "value" => 'bar', 'versions' => [] }
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
237
|
+
its(:title_translations_raw) { should == @expected_translations }
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "when field is not updated" do
|
241
|
+
before do
|
242
|
+
@entry.title = 'foo'
|
243
|
+
@entry.title_with_default = 'bar'
|
244
|
+
I18n.locale = :es
|
245
|
+
@entry.title = 'spanishfoo'
|
246
|
+
I18n.locale = :en
|
247
|
+
@entry.save
|
248
|
+
@entry.title = 'baz'
|
249
|
+
@entry.save
|
250
|
+
@expected_title_translations = {
|
251
|
+
'en' => {
|
252
|
+
"value" => "baz",
|
253
|
+
"versions" => [
|
254
|
+
{ "version" => 0, "value" => 'foo' },
|
255
|
+
{ "version" => 1, "value" => 'baz' }
|
256
|
+
]
|
257
|
+
},
|
258
|
+
'es' => {
|
259
|
+
"value" => "spanishfoo",
|
260
|
+
"versions" => [
|
261
|
+
{ "version" => 0, "value" => 'spanishfoo' }
|
262
|
+
]
|
263
|
+
}
|
264
|
+
}
|
265
|
+
@expected_title_with_default_translations = {
|
266
|
+
'en' => {
|
267
|
+
"value" => "bar",
|
268
|
+
"versions" => [
|
269
|
+
{ "version" => 0, "value" => 'bar' }
|
270
|
+
]
|
271
|
+
}
|
272
|
+
}
|
273
|
+
end
|
274
|
+
|
275
|
+
its(:title_translations_raw) { should == @expected_title_translations }
|
276
|
+
its(:title_with_default_translations_raw) { should == @expected_title_with_default_translations }
|
277
|
+
end
|
278
|
+
|
279
|
+
describe "when field is updated, saved, updated, and then saved" do
|
280
|
+
before do
|
281
|
+
@entry.title = 'foo'
|
282
|
+
@entry.save
|
283
|
+
@entry.title = 'bar'
|
284
|
+
@entry.save
|
285
|
+
@expected_translations = {
|
286
|
+
'en' => {
|
287
|
+
"value" => "bar",
|
288
|
+
"versions" => [
|
289
|
+
{ "version" => 0, "value" => 'foo' },
|
290
|
+
{ "version" => 1, "value" => 'bar' }
|
291
|
+
]
|
292
|
+
}
|
293
|
+
}
|
294
|
+
end
|
295
|
+
|
296
|
+
its(:title_translations_raw) { should == @expected_translations }
|
297
|
+
end
|
298
|
+
|
299
|
+
describe "when field is updated with the same value" do
|
300
|
+
before do
|
301
|
+
@entry.title = 'foo'
|
302
|
+
@entry.save
|
303
|
+
@entry.title = 'foo'
|
304
|
+
@entry.save
|
305
|
+
@expected_translations = {
|
306
|
+
'en' => {
|
307
|
+
"value" => "foo",
|
308
|
+
"versions" => [
|
309
|
+
{ "version" => 0, "value" => 'foo' }
|
310
|
+
]
|
311
|
+
}
|
312
|
+
}
|
313
|
+
end
|
314
|
+
|
315
|
+
its(:title_translations_raw) { should == @expected_translations }
|
316
|
+
its(:verbalized_versions) { should have(1).item }
|
317
|
+
end
|
318
|
+
|
319
|
+
describe "embedded document" do
|
320
|
+
before do
|
321
|
+
class Entry
|
322
|
+
include Mongoid::Document
|
323
|
+
include Mongoid::Verbalize
|
324
|
+
include Mongoid::Verbalize::Versioning
|
325
|
+
|
326
|
+
verbalized_field :title
|
327
|
+
embeds_many :sub_entries
|
328
|
+
end
|
329
|
+
|
330
|
+
class SubEntry
|
331
|
+
include Mongoid::Document
|
332
|
+
include Mongoid::Verbalize
|
333
|
+
verbalized_field :subtitle
|
334
|
+
embedded_in :entry
|
335
|
+
end
|
336
|
+
@entry = Entry.new(:title => 'Selfridges')
|
337
|
+
@sub_entry = @entry.sub_entries.build(:subtitle => 'Oxford Street')
|
338
|
+
@entry.save
|
339
|
+
@entry.save
|
340
|
+
@entry.reload
|
341
|
+
@sub_entry = @entry.sub_entries.first
|
342
|
+
@expected_title_translations = {
|
343
|
+
'en' => {
|
344
|
+
"value" => "Selfridges",
|
345
|
+
"versions" => [
|
346
|
+
{ "version" => 0, "value" => 'Selfridges' }
|
347
|
+
]
|
348
|
+
}
|
349
|
+
}
|
350
|
+
@expected_subtitle_translations = {
|
351
|
+
'en' => {
|
352
|
+
"value" => "Oxford Street",
|
353
|
+
"versions" => [
|
354
|
+
{ "version" => 0, "value" => 'Oxford Street' }
|
355
|
+
]
|
356
|
+
}
|
357
|
+
}
|
358
|
+
end
|
359
|
+
|
360
|
+
describe "entry" do
|
361
|
+
subject { @entry }
|
362
|
+
its(:verbalized_versions) { should have(1).item }
|
363
|
+
its(:title_translations_raw) { should == @expected_title_translations }
|
364
|
+
end
|
365
|
+
|
366
|
+
describe "subentry" do
|
367
|
+
subject { @sub_entry }
|
368
|
+
it { should_not respond_to(:verbalized_versions) }
|
369
|
+
its(:subtitle_translations_raw) { should == @expected_subtitle_translations }
|
370
|
+
end
|
371
|
+
|
372
|
+
describe "when subentry is updated" do
|
373
|
+
before do
|
374
|
+
@sub_entry.subtitle = 'Regent Street'
|
375
|
+
@entry.save
|
376
|
+
#@entry.reload
|
377
|
+
end
|
378
|
+
|
379
|
+
describe "entry" do
|
380
|
+
subject { @entry }
|
381
|
+
its(:verbalized_versions) { should have(2).items }
|
382
|
+
its("verbalized_versions.first.version") { should == 0 }
|
383
|
+
its("verbalized_versions.second.version") { should == 1 }
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
describe Mongoid::Verbalize, 'localized field in embedded association' do
|
391
|
+
before do
|
392
|
+
class Entry
|
393
|
+
embeds_many :sub_entries
|
394
|
+
end
|
395
|
+
|
396
|
+
class SubEntry
|
397
|
+
include Mongoid::Document
|
398
|
+
include Mongoid::Verbalize
|
399
|
+
verbalized_field :title
|
400
|
+
embedded_in :entry, :inverse_of => :sub_entries
|
401
|
+
end
|
402
|
+
@entry = Entry.new
|
403
|
+
@sub_entries = (0..2).map { @entry.sub_entries.build }
|
404
|
+
end
|
405
|
+
|
406
|
+
it "should contain the embedded documents" do
|
407
|
+
@entry.sub_entries.criteria.instance_variable_get("@documents").should == @sub_entries
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
describe Mongoid::Verbalize, 'localized field in embedded document' do
|
412
|
+
before do
|
413
|
+
class Entry
|
414
|
+
embeds_one :sub_entry
|
415
|
+
end
|
416
|
+
|
417
|
+
class SubEntry
|
418
|
+
include Mongoid::Document
|
419
|
+
include Mongoid::Verbalize
|
420
|
+
verbalized_field :subtitle
|
421
|
+
embedded_in :entry, :inverse_of => :sub_entries
|
422
|
+
end
|
423
|
+
@entry = Entry.new
|
424
|
+
@entry.create_sub_entry(:subtitle => 'Oxford Street')
|
425
|
+
end
|
426
|
+
|
427
|
+
it "should store the title in the right locale" do
|
428
|
+
@entry.reload.sub_entry.subtitle.should == 'Oxford Street'
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
describe Mongoid::Verbalize, "verbalized_field with :use_default_if_empty => true" do
|
433
|
+
before do
|
434
|
+
I18n.default_locale = :en
|
435
|
+
I18n.locale = :en
|
436
|
+
end
|
437
|
+
|
438
|
+
describe "without an assigned value" do
|
439
|
+
before do
|
440
|
+
@entry = Entry.new
|
441
|
+
end
|
442
|
+
|
443
|
+
it "should return blank" do
|
444
|
+
@entry.title_with_default.should be_blank
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
describe "with an assigned value in the default locale" do
|
449
|
+
before do
|
450
|
+
@entry = Entry.new(:title_with_default => 'Title with default')
|
451
|
+
end
|
452
|
+
|
453
|
+
it "should return that value with the default locale" do
|
454
|
+
@entry.title_with_default.should == 'Title with default'
|
455
|
+
end
|
456
|
+
|
457
|
+
describe "when the locale is changed" do
|
458
|
+
before do
|
459
|
+
I18n.locale = :it
|
460
|
+
end
|
461
|
+
|
462
|
+
it "should return the value of the default locale" do
|
463
|
+
@entry.title_with_default.should == 'Title with default'
|
464
|
+
end
|
465
|
+
|
466
|
+
describe "when a new value is assigned" do
|
467
|
+
before do
|
468
|
+
@entry.title_with_default = 'Titolo con default'
|
469
|
+
end
|
470
|
+
|
471
|
+
it "should return the new value" do
|
472
|
+
@entry.title_with_default.should == 'Titolo con default'
|
473
|
+
end
|
474
|
+
|
475
|
+
describe "if we go back to the original locale" do
|
476
|
+
before do
|
477
|
+
I18n.locale = :en
|
478
|
+
end
|
479
|
+
|
480
|
+
it "should return the original value" do
|
481
|
+
@entry.title_with_default.should == 'Title with default'
|
482
|
+
end
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
describe Mongoid::Verbalize, "verbalized_field with validation 'validates_default_locale'" do
|
490
|
+
before do
|
491
|
+
I18n.default_locale = :en
|
492
|
+
I18n.locale = :it
|
493
|
+
@entry = EntryWithValidations.new
|
494
|
+
end
|
495
|
+
|
496
|
+
describe "when run entry validations and default locale translation wasn't set" do
|
497
|
+
before do
|
498
|
+
@entry.title_validated_with_default_locale = "Titolo"
|
499
|
+
@entry.valid?
|
500
|
+
end
|
501
|
+
|
502
|
+
it "is added a 'locale_blank' error for that field to entry errors list" do
|
503
|
+
@entry.errors.include?(:title_validated_with_default_locale).should be_true
|
504
|
+
@entry.errors[:title_validated_with_default_locale][0].split('.').last.should == 'locale_blank'
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
describe "when run entry validations and default locale translation was set" do
|
509
|
+
before do
|
510
|
+
@entry.title_validated_with_default_locale_translations_raw={'en'=>'Title'}
|
511
|
+
@entry.valid?
|
512
|
+
end
|
513
|
+
|
514
|
+
it "no error for that field is added to entry errors list" do
|
515
|
+
@entry.errors.include?(:title_validated_with_default_locale).should be_false
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
describe Mongoid::Verbalize, "verbalized_field with validation 'validates_one_locale'" do
|
521
|
+
before do
|
522
|
+
I18n.default_locale = :en
|
523
|
+
I18n.locale = :it
|
524
|
+
@entry = EntryWithValidations.new
|
525
|
+
end
|
526
|
+
|
527
|
+
describe "when run entry validations and no translation was set" do
|
528
|
+
before do
|
529
|
+
@entry.valid?
|
530
|
+
end
|
531
|
+
|
532
|
+
it "is added a 'locale_blank' error for that field to entry errors list" do
|
533
|
+
@entry.errors.include?(:title_validated_with_one_locale).should be_true
|
534
|
+
@entry.errors[:title_validated_with_one_locale][0].split('.').last.should == 'all_locales_blank'
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
describe "when run entry validations and a locale translation was set" do
|
539
|
+
before do
|
540
|
+
@entry.title_validated_with_one_locale_translations_raw={'it'=>'Titolo'}
|
541
|
+
@entry.valid?
|
542
|
+
end
|
543
|
+
|
544
|
+
it "no error for that field is added to entry errors list" do
|
545
|
+
@entry.errors.include?(:title_validated_with_one_locale).should be_false
|
546
|
+
end
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
describe Mongoid::Verbalize, "verbalized_field with validation 'validates_all_locales'" do
|
551
|
+
before do
|
552
|
+
I18n.default_locale = :en
|
553
|
+
I18n.available_locales = [:en, :it, :de, :fr]
|
554
|
+
I18n.locale = :it
|
555
|
+
@entry = EntryWithValidations.new
|
556
|
+
end
|
557
|
+
|
558
|
+
describe "when run entry validations and not all translations were set" do
|
559
|
+
before do
|
560
|
+
@entry.title_validated_with_all_locales_translations_raw={'it'=>'Titolo', 'en'=>'Title'}
|
561
|
+
@entry.valid?
|
562
|
+
end
|
563
|
+
|
564
|
+
it "is added a 'locale_blank' error for that field for each missing locale" do
|
565
|
+
@entry.errors.include?(:title_validated_with_all_locales).should be_true
|
566
|
+
@entry.errors[:title_validated_with_all_locales].count.should == 2
|
567
|
+
@entry.errors[:title_validated_with_all_locales][0].split('.').last.should == 'locale_blank'
|
568
|
+
@entry.errors[:title_validated_with_all_locales][1].split('.').last.should == 'locale_blank'
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
describe "when run entry validations and all available locales translation were set" do
|
573
|
+
before do
|
574
|
+
@entry.title_validated_with_all_locales_translations_raw={'it'=>'Titolo', 'en'=>'Title', 'fr'=>'Titre', 'de'=>'Titel'}
|
575
|
+
@entry.valid?
|
576
|
+
end
|
577
|
+
|
578
|
+
it "no error for that field is added to entry errors list" do
|
579
|
+
@entry.errors.include?(:title_validated_with_all_locales).should be_false
|
580
|
+
end
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
describe Mongoid::Verbalize, "create_accessors" do
|
585
|
+
before do
|
586
|
+
I18n.locale = :en
|
587
|
+
@entry = Entry.new
|
588
|
+
end
|
589
|
+
|
590
|
+
it "should not affect other fields accessors" do
|
591
|
+
@entry.weight.should == 60
|
592
|
+
|
593
|
+
@entry.weight = 70
|
594
|
+
@entry.weight.should == 70
|
595
|
+
end
|
596
|
+
|
597
|
+
it "should not define own methods on for fields" do
|
598
|
+
@entry.should_not respond_to :weight_translations
|
599
|
+
end
|
600
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'mongoid'
|
5
|
+
require 'mongoid/verbalize'
|
6
|
+
|
7
|
+
require 'rspec'
|
8
|
+
|
9
|
+
Mongoid.configure do |config|
|
10
|
+
config.connect_to('mongoid_verbalize_test')
|
11
|
+
end
|
12
|
+
# Mongoid.logger = Logger.new($stdout)
|
13
|
+
# Mongoid.logger.level = Logger::DEBUG
|
14
|
+
# Moped.logger.level = Logger::DEBUG
|
15
|
+
# Moped.logger = Logger.new($stdout)
|
16
|
+
|
17
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.mock_with :rspec
|
21
|
+
config.after(:each) { Mongoid.purge! }
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongoid-verbalize
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tim Jones
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mongoid
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - <=
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '4.0'
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '3.0'
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - <=
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '4.0'
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '3.0'
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.9.2
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 0.9.2
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: rspec
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 2.12.0
|
60
|
+
type: :development
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 2.12.0
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: yard
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0.8'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: debugger
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
description: Fine-grained versioning and localization for Mongoid documents
|
101
|
+
email:
|
102
|
+
- tim@timjones.tw
|
103
|
+
executables: []
|
104
|
+
extensions: []
|
105
|
+
extra_rdoc_files: []
|
106
|
+
files:
|
107
|
+
- lib/mongoid/verbalize/fields.rb
|
108
|
+
- lib/mongoid/verbalize/selector.rb
|
109
|
+
- lib/mongoid/verbalize/translated_string.rb
|
110
|
+
- lib/mongoid/verbalize/verbalized_validator.rb
|
111
|
+
- lib/mongoid/verbalize/verbalized_version.rb
|
112
|
+
- lib/mongoid/verbalize/versioning.rb
|
113
|
+
- lib/mongoid/verbalize.rb
|
114
|
+
- spec/mongoid/verbalize_spec.rb
|
115
|
+
- spec/spec_helper.rb
|
116
|
+
- LICENSE
|
117
|
+
- README.md
|
118
|
+
- Rakefile
|
119
|
+
- Gemfile
|
120
|
+
- .rspec
|
121
|
+
homepage: https://github.com/tgjones/mongoid-verbalize
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
hash: 458357717130051605
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
hash: 458357717130051605
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 1.8.23
|
149
|
+
signing_key:
|
150
|
+
specification_version: 3
|
151
|
+
summary: Fine-grained versioning and localization for Mongoid documents
|
152
|
+
test_files: []
|
153
|
+
has_rdoc:
|