From da2d689bdc8d90ac2c54965fb00660b9b283d250 Mon Sep 17 00:00:00 2001 From: Didier Lafforgue Date: Sat, 26 May 2012 14:35:04 +0200 Subject: [PATCH] fix issue #412 --- .../locomotive/extensions/page/redirect.rb | 2 +- config/locales/default.en.yml | 5 ++ config/locales/default.fr.yml | 4 ++ lib/locomotive/mongoid/patches.rb | 56 ++++++++++++++++--- script/upgrade_v1.1.rb | 46 +++++++++++++++ script/upgrade_v1.rb | 2 +- .../extensions/page/redirect_spec.rb | 22 ++++++++ spec/models/locomotive/page_spec.rb | 2 +- 8 files changed, 127 insertions(+), 12 deletions(-) create mode 100755 script/upgrade_v1.1.rb create mode 100644 spec/models/locomotive/extensions/page/redirect_spec.rb diff --git a/app/models/locomotive/extensions/page/redirect.rb b/app/models/locomotive/extensions/page/redirect.rb index 8b9f2300..7ce9f959 100644 --- a/app/models/locomotive/extensions/page/redirect.rb +++ b/app/models/locomotive/extensions/page/redirect.rb @@ -9,7 +9,7 @@ module Locomotive ## fields ## field :redirect, :type => Boolean, :default => false - field :redirect_url, :type => String + field :redirect_url, :type => String, :localize => true ## validations ## validates_presence_of :redirect_url, :if => :redirect diff --git a/config/locales/default.en.yml b/config/locales/default.en.yml index 18ecdaa1..6884afc4 100644 --- a/config/locales/default.en.yml +++ b/config/locales/default.en.yml @@ -3,6 +3,11 @@ en: formats: default: "%m/%d/%Y" + mongoid: + errors: + messages: + blank_on_locale: "can't be blank" + errors: messages: domain_taken: "%{value} is already taken" diff --git a/config/locales/default.fr.yml b/config/locales/default.fr.yml index d3a9b332..447f7985 100644 --- a/config/locales/default.fr.yml +++ b/config/locales/default.fr.yml @@ -53,6 +53,10 @@ fr: body: "{% extends 'parent' %}" mongoid: + errors: + messages: + blank_on_locale: "doit ĂȘtre rempli(e)" + attributes: locomotive/page: title: Titre diff --git a/lib/locomotive/mongoid/patches.rb b/lib/locomotive/mongoid/patches.rb index 365b781b..227b319f 100644 --- a/lib/locomotive/mongoid/patches.rb +++ b/lib/locomotive/mongoid/patches.rb @@ -48,21 +48,59 @@ module Mongoid#:nodoc: # make the validators work with localized field module Validations #:nodoc: - def read_attribute_for_validation_with_localization(attr) - if fields[attr.to_s] && fields[attr.to_s].localized? - send(attr.to_sym) - else - read_attribute_for_validation_without_localization(attr) + + class ExclusionValidator < ActiveModel::Validations::ExclusionValidator + include Localizable + end + + class UniquenessValidator < ActiveModel::EachValidator + + def to_validate_with_localization(document, attribute, value) + field = document.fields[attribute.to_s] + if field.try(:localized?) + # no need of the translations, just the current value + value = document.send(attribute.to_sym) + end + to_validate_without_localization(document, attribute, value) + end + + alias_method_chain :to_validate, :localization + + end + + module ClassMethods + def validates_exclusion_of(*args) + validates_with(ExclusionValidator, _merge_attributes(args)) end end - alias_method_chain :read_attribute_for_validation, :localization + module LocalizedEachValidator - class PresenceValidator < ActiveModel::EachValidator - def validate_each(document, attribute, value) - document.errors.add(attribute, :blank, options) if value.blank? + # Performs validation on the supplied record. By default this will call + # +validates_each+ to determine validity therefore subclasses should + # override +validates_each+ with validation logic. + def validate(record) + attributes.each do |attribute| + field = record.fields[attribute.to_s] + + # make sure that we use the localized value and not the translations when we test the allow_nil and allow_blank options + value = field.try(:localized?) ? record.send(attribute.to_sym) : record.read_attribute_for_validation(attribute) + + next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank]) + + # use the translations of the localized field for the next part + value = record.read_attribute_for_validation(attribute) if field.try(:localized?) + + validate_each(record, attribute, value) + end end + end + + [FormatValidator, LengthValidator, PresenceValidator, UniquenessValidator, ExclusionValidator].each do |klass| + klass.send(:include, LocalizedEachValidator) + end + end end diff --git a/script/upgrade_v1.1.rb b/script/upgrade_v1.1.rb new file mode 100755 index 00000000..0ad2327f --- /dev/null +++ b/script/upgrade_v1.1.rb @@ -0,0 +1,46 @@ +#!/usr/bin/env ruby +begin + require 'bundler/setup' +rescue LoadError + puts 'You must `gem install bundler` and `bundle install` to run rake tasks' +end + +# ================ GLOBAL VARIABLES ============== + +$database_name = 'locomotive_engine_dev' +$database_host = 'localhost' +$database_port = '27017' +# $database_username = '' +# $database_password = '' + +$default_locale = 'en' +$locale_exceptions = {} + +# ================ MONGODB ============== + +require 'mongoid' + +Mongoid.configure do |config| + db = config.master = Mongo::Connection.new($database_host, $database_port).db($database_name) + if $database_username && $database_password + db.authenticate($database_username, $database_password) + end +end + +db = Mongoid.config.master + +def get_locale(site_id) + $locale_exceptions[site_id.to_s] || $default_locale +end + +# locomotive_pages + +# localize redirect_url +collection = db.collections.detect { |c| c.name == 'locomotive_pages' } +collection.find.each do |page| + next if !page['redirect'] || page['redirect_url'].is_a?(Hash) + + locale = get_locale(page['site_id']) + + collection.update({ '_id' => page['_id'] }, { '$set' => { 'redirect_url' => { locale => page['redirect_url'] } } }) +end \ No newline at end of file diff --git a/script/upgrade_v1.rb b/script/upgrade_v1.rb index 06fa96f4..7b3c65b8 100755 --- a/script/upgrade_v1.rb +++ b/script/upgrade_v1.rb @@ -303,7 +303,7 @@ if collection = db.collections.detect { |c| c.name == 'pages' } modifications['locales'] = [locale] modifications['response_type'] = 'text/html' - %w(title slug fullpath raw_template serialized_template template_dependencies snippet_dependencies seo_title meta_keywords meta_description).each do |attr| + %w(title slug fullpath raw_template serialized_template template_dependencies snippet_dependencies seo_title meta_keywords meta_description redirect_url).each do |attr| modifications[attr] = { locale => page[attr] } end diff --git a/spec/models/locomotive/extensions/page/redirect_spec.rb b/spec/models/locomotive/extensions/page/redirect_spec.rb new file mode 100644 index 00000000..1db44428 --- /dev/null +++ b/spec/models/locomotive/extensions/page/redirect_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe Locomotive::Extensions::Page::Redirect do + + let(:page) { Factory.build(:page, :redirect => true, :redirect_url => 'http://www.locomotivecms.com') } + + describe 'redirect option enabled' do + + it 'is valid' do + page.valid? + page.errors[:redirect_url].should be_blank + end + + it 'requires the presence of the redirect url' do + page.redirect_url = '' + page.valid? + page.errors[:redirect_url].should == ["can't be blank"] + end + + end + +end \ No newline at end of file diff --git a/spec/models/locomotive/page_spec.rb b/spec/models/locomotive/page_spec.rb index b02075ad..1f50ba65 100644 --- a/spec/models/locomotive/page_spec.rb +++ b/spec/models/locomotive/page_spec.rb @@ -48,7 +48,7 @@ describe Locomotive::Page do end %w{admin locomotive stylesheets images javascripts}.each do |slug| - it "considers '#{slug}' as invalid" do + it "considers '#{slug}' as an invalid slug" do page = FactoryGirl.build(:page, :slug => slug) page.stubs(:depth).returns(1) page.should_not be_valid