Merge branch 'rails3.beta4'

This commit is contained in:
dinedine 2010-07-20 12:18:16 +02:00
commit f1b432641d
27 changed files with 98 additions and 148 deletions

View File

@ -2,12 +2,13 @@
source 'http://gemcutter.org' source 'http://gemcutter.org'
source 'http://gems.github.com' source 'http://gems.github.com'
gem 'rails', '3.0.0.beta3' gem 'rails', '3.0.0.beta4'
gem 'liquid', '2.0.0' gem 'liquid', '2.0.0'
gem 'bson_ext', '>= 1.0.1' gem 'bson_ext', '>= 1.0.1'
gem 'mongo_ext' gem 'mongo_ext'
gem 'mongoid', '2.0.0.beta6' # gem 'mongoid', :git => 'git@github.com:did/mongoid.git'
gem 'mongoid-locomotive'
gem 'mongoid_acts_as_tree', '0.1.5' gem 'mongoid_acts_as_tree', '0.1.5'
gem 'mongo_session_store', '2.0.0.pre' gem 'mongo_session_store', '2.0.0.pre'
gem 'warden' gem 'warden'
@ -15,7 +16,6 @@ gem 'devise', '1.1.rc1'
gem 'haml', '3.0.1' gem 'haml', '3.0.1'
gem 'rmagick', '2.12.2' gem 'rmagick', '2.12.2'
gem 'aws' gem 'aws'
gem 'jeweler'
gem 'mimetype-fu', :require => 'mimetype_fu' gem 'mimetype-fu', :require => 'mimetype_fu'
gem 'formtastic-rails3', :require => 'formtastic' gem 'formtastic-rails3', :require => 'formtastic'
gem 'carrierwave-rails3', :require => 'carrierwave' gem 'carrierwave-rails3', :require => 'carrierwave'
@ -24,6 +24,7 @@ gem 'heroku'
gem 'httparty', '0.6.0' gem 'httparty', '0.6.0'
gem 'RedCloth' gem 'RedCloth'
gem 'inherited_resources', '1.1.2' gem 'inherited_resources', '1.1.2'
gem 'jeweler'
# Development environment # Development environment
group :development do group :development do
@ -36,7 +37,7 @@ end
group :test do group :test do
gem 'rspec-rails', '2.0.0.beta.11' gem 'rspec-rails', '2.0.0.beta.11'
gem 'factory_girl', :git => 'git://github.com/thoughtbot/factory_girl.git', :branch => 'rails3' gem 'factory_girl_rails'
gem 'capybara' gem 'capybara'
gem 'cucumber' gem 'cucumber'
gem 'cucumber-rails' gem 'cucumber-rails'

View File

@ -28,7 +28,7 @@ begin
"{vendor}/**/*"] "{vendor}/**/*"]
# other fields that would normally go in your gemspec # other fields that would normally go in your gemspec
# like authors, email and has_rdoc can also be included here # like authors, email and has_rdoc can also be included here
bundle = Bundler::Definition.from_gemfile('Gemfile') bundle = Bundler::Definition.build('Gemfile', 'Gemfile.lock', false)
bundle.dependencies.each do |dep| bundle.dependencies.each do |dep|
if dep.groups.include?(:default) if dep.groups.include?(:default)
gem.add_dependency(dep.name, dep.requirement.to_s) gem.add_dependency(dep.name, dep.requirement.to_s)
@ -36,7 +36,7 @@ begin
end end
end end
Jeweler::GemcutterTasks.new Jeweler::GemcutterTasks.new
rescue rescue Exception => e
puts "Jeweler or one of its dependencies is not installed." puts "Jeweler or one of its dependencies is not installed. #{e.inspect}"
end end

View File

@ -15,7 +15,7 @@ class AssetCollection
liquid_methods :name, :ordered_assets liquid_methods :name, :ordered_assets
## callbacks ## ## callbacks ##
before_validate :normalize_slug before_validation :normalize_slug
before_save :store_asset_positions! before_save :store_asset_positions!
## validations ## ## validations ##

View File

@ -20,7 +20,7 @@ class ContentType
end end
## callbacks ## ## callbacks ##
before_validate :normalize_slug before_validation :normalize_slug
before_save :set_default_values before_save :set_default_values
## validations ## ## validations ##

View File

@ -13,7 +13,7 @@ module Models
field :content_type_visible_column field :content_type_visible_column
before_validate :set_slug_if_templatized before_validation :set_slug_if_templatized
end end
module InstanceMethods module InstanceMethods

View File

@ -15,7 +15,7 @@ module Models
acts_as_tree :order => ['position', 'asc'] acts_as_tree :order => ['position', 'asc']
## callbacks ## ## callbacks ##
before_validate :reset_parent before_validation :reset_parent
before_save { |p| p.send(:write_attribute, :parent_id, nil) if p.parent_id.blank? } before_save { |p| p.send(:write_attribute, :parent_id, nil) if p.parent_id.blank? }
before_save :change_parent before_save :change_parent
before_create { |p| p.send(:fix_position, false) } before_create { |p| p.send(:fix_position, false) }

View File

@ -11,7 +11,7 @@ class LiquidTemplate
belongs_to_related :site belongs_to_related :site
## callbacks ## ## callbacks ##
before_validate :normalize_slug before_validation :normalize_slug
## validations ## ## validations ##
validates_presence_of :site, :name, :slug, :value validates_presence_of :site, :name, :slug, :value

View File

@ -21,7 +21,7 @@ class Page
embeds_many :parts, :class_name => 'PagePart' embeds_many :parts, :class_name => 'PagePart'
## callbacks ## ## callbacks ##
before_validate :normalize_slug before_validation :normalize_slug
before_save { |p| p.fullpath = p.fullpath(true) } before_save { |p| p.fullpath = p.fullpath(true) }
before_destroy :do_not_remove_index_and_404_pages before_destroy :do_not_remove_index_and_404_pages

View File

@ -17,8 +17,8 @@ class ThemeAsset
belongs_to_related :site belongs_to_related :site
## callbacks ## ## callbacks ##
before_validate :sanitize_slug before_validation :sanitize_slug
before_validate :store_plain_text before_validation :store_plain_text
before_save :set_slug before_save :set_slug
## validations ## ## validations ##

View File

@ -1,2 +1,2 @@
%p.tcenter %p.tcenter
= t('.who_is_behind', :development => nocoffee_tag) = preserve(t('.who_is_behind', :development => nocoffee_tag))

View File

@ -1,7 +1,7 @@
%h1= link_to current_site.name, '#' %h1= link_to current_site.name, '#'
#global-actions-bar #global-actions-bar
= t('.welcome', :name => link_to(current_admin.name, edit_admin_my_account_url)) = preserve(t('.welcome', :name => link_to(current_admin.name, edit_admin_my_account_url)))
%span= '|' %span= '|'
= link_to t('.see'), main_site_url = link_to t('.see'), main_site_url
%span= '|' %span= '|'

View File

@ -11,7 +11,7 @@ en:
shared: shared:
header: header:
welcome: Welcome, {{name}} welcome: Welcome, %{name}
see: See website see: See website
logout: Log out logout: Log out
menu: menu:
@ -25,7 +25,7 @@ en:
site: Site site: Site
theme_assets: Theme files theme_assets: Theme files
footer: footer:
who_is_behind: "Service developed by {{development}} and designed by <a href=\"http://www.sachagreif.com\">Sacha Greif</a>" who_is_behind: "Service developed by %{development} and designed by <a href=\"http://www.sachagreif.com\">Sacha Greif</a>"
form_actions: form_actions:
back: Back without saving back: Back without saving
create: Create create: Create
@ -76,7 +76,7 @@ en:
index: index:
title: Listing pages title: Listing pages
help: "Pages are organized as a tree. You can order pages as well as folders" help: "Pages are organized as a tree. You can order pages as well as folders"
no_items: "There are no pages for now. Just click <a href=\"{{url}}\">here</a> to create the first one." no_items: "There are no pages for now. Just click <a href=\"%{url}\">here</a> to create the first one."
new: new page new: new page
lastest_items: Lastest pages lastest_items: Lastest pages
new: new:
@ -101,7 +101,7 @@ en:
index: index:
title: Listing layouts title: Listing layouts
help: "Layouts give the look of a page (1, 2 or many columns)." help: "Layouts give the look of a page (1, 2 or many columns)."
no_items: "There are no layouts for now. Just click <a href=\"{{url}}\">here</a> to create the first one." no_items: "There are no layouts for now. Just click <a href=\"%{url}\">here</a> to create the first one."
new: new layout new: new layout
new: new:
title: New layout title: New layout
@ -117,7 +117,7 @@ en:
index: index:
title: Listing snippets title: Listing snippets
help: "Snippets are portion of HTML code which can be found at different places within the site (such as a footer)." help: "Snippets are portion of HTML code which can be found at different places within the site (such as a footer)."
no_items: "There are no snippets for now. Just click <a href=\"{{url}}\">here</a> to create the first one." no_items: "There are no snippets for now. Just click <a href=\"%{url}\">here</a> to create the first one."
new: new snippet new: new snippet
new: new:
title: New snippet title: New snippet
@ -166,13 +166,13 @@ en:
fonts: Fonts fonts: Fonts
images: Images images: Images
flashes: Flash flashes: Flash
no_items: "There are no files for now. Just click <a href=\"{{url}}\">here</a> to create the first one." no_items: "There are no files for now. Just click <a href=\"%{url}\">here</a> to create the first one."
new: new:
title: New file title: New file
help: "You have the choice to either upload any file or to copy/paste a stylesheet or a javascript in plain text." help: "You have the choice to either upload any file or to copy/paste a stylesheet or a javascript in plain text."
edit: edit:
title: "Editing {{file}}" title: "Editing %{file}"
help: "You can use it by copying/pasting the following url: {{url}}" help: "You can use it by copying/pasting the following url: %{url}"
form: form:
picker_link: Insert a file into the code picker_link: Insert a file into the code
choose_file: Choose file choose_file: Choose file
@ -186,7 +186,7 @@ en:
title: Asset collections title: Asset collections
help: "The collection name can be updated by clicking it. You can customize assets in a collection by adding new fields." help: "The collection name can be updated by clicking it. You can customize assets in a collection by adding new fields."
new: new collection new: new collection
no_items: "There are no collections for now. Just click <a href=\"{{url}}\">here</a> to create the first one." no_items: "There are no collections for now. Just click <a href=\"%{url}\">here</a> to create the first one."
new: new:
title: New collection title: New collection
help: "For now, just type a name. Other settings will come once the form is sent." help: "For now, just type a name. Other settings will come once the form is sent."
@ -194,7 +194,7 @@ en:
help: "The collection name can be updated by clicking it. You can customize assets in a collection by adding new fields." help: "The collection name can be updated by clicking it. You can customize assets in a collection by adding new fields."
add_asset: add asset add_asset: add asset
destroy: remove collection destroy: remove collection
no_items: "There are no assets for now. Just click <a href=\"{{url}}\">here</a> to create the first one." no_items: "There are no assets for now. Just click <a href=\"%{url}\">here</a> to create the first one."
ask_for_name: "Please type the new name" ask_for_name: "Please type the new name"
assets: assets:
@ -223,7 +223,7 @@ en:
contents: contents:
index: index:
title: 'Listing "{{type}}"' title: 'Listing "%{type}"'
edit: edit model edit: edit model
destroy: remove model destroy: remove model
download: download items download: download items
@ -232,11 +232,11 @@ en:
lastest_items: "Lastest items" lastest_items: "Lastest items"
updated_at: "Updated at" updated_at: "Updated at"
list: list:
no_items: "There are no items for now. Just click <a href=\"{{url}}\">here</a> to create the first one." no_items: "There are no items for now. Just click <a href=\"%{url}\">here</a> to create the first one."
new: new:
title: '{{type}} &mdash; new item' title: '%{type} &mdash; new item'
edit: edit:
title: '{{type}} &mdash; editing item' title: '%{type} &mdash; editing item'
image_picker: image_picker:
link: Insert an image into the code link: Insert an image into the code

View File

@ -33,7 +33,7 @@ fr:
shared: shared:
header: header:
welcome: Bonjour, {{name}} welcome: Bonjour, %{name}
see: Voir le site web see: Voir le site web
logout: Se déconnecter logout: Se déconnecter
menu: menu:
@ -47,7 +47,7 @@ fr:
site: Site site: Site
theme_assets: Fichiers Thème theme_assets: Fichiers Thème
footer: footer:
who_is_behind: "Service développé par {{development}} et désigné par <a href=\"http://www.sachagreif.com\">Sacha Greif</a>" who_is_behind: "Service développé par %{development} et désigné par <a href=\"http://www.sachagreif.com\">Sacha Greif</a>"
form_actions: form_actions:
back: Retour sans sauvegarder back: Retour sans sauvegarder
create: Créer create: Créer
@ -98,7 +98,7 @@ fr:
index: index:
title: Liste des pages title: Liste des pages
help: "Les pages sont organisées sous forme d'un arbre. Vous pouvez classes les pages ainsi que les dossiers." help: "Les pages sont organisées sous forme d'un arbre. Vous pouvez classes les pages ainsi que les dossiers."
no_items: "Il n'existe pas de page. Vous pouvez commencer par créer une <a href='{{url}}'>ici</a>." no_items: "Il n'existe pas de page. Vous pouvez commencer par créer une <a href='%{url}'>ici</a>."
new: nouvelle page new: nouvelle page
lastest_items: Dernières pages lastest_items: Dernières pages
new: new:
@ -123,7 +123,7 @@ fr:
index: index:
title: Liste gabarits title: Liste gabarits
help: "Les gabarits permettent de définir le squelette d'une page (1, 2 ou plusieurs colonnes)." help: "Les gabarits permettent de définir le squelette d'une page (1, 2 ou plusieurs colonnes)."
no_items: "Il n'existe pas de gabarit. Vous pouvez commencer par créer un <a href='{{url}}'>ici</a>." no_items: "Il n'existe pas de gabarit. Vous pouvez commencer par créer un <a href='%{url}'>ici</a>."
new: nouveau gabarit new: nouveau gabarit
new: new:
title: Nouveau gabarit title: Nouveau gabarit
@ -139,7 +139,7 @@ fr:
index: index:
title: Liste des snippets title: Liste des snippets
help: "Les snippets sont des bouts de code HTML qui se répetent à travers le site (tel que le bas-de-page par exemple)." help: "Les snippets sont des bouts de code HTML qui se répetent à travers le site (tel que le bas-de-page par exemple)."
no_items: "Il n'existe pas de snippet. Vous pouvez commencer par créer un <a href='{{url}}'>ici</a>." no_items: "Il n'existe pas de snippet. Vous pouvez commencer par créer un <a href='%{url}'>ici</a>."
new: nouveau snippet new: nouveau snippet
new: new:
title: "Nouveau snippet" title: "Nouveau snippet"
@ -188,13 +188,13 @@ fr:
images: Images images: Images
flashes: Flash flashes: Flash
fonts: Polices fonts: Polices
no_items: "Il n'existe pas de fichiers. Vous pouvez commencer par créer un <a href='{{url}}'>ici</a>." no_items: "Il n'existe pas de fichiers. Vous pouvez commencer par créer un <a href='%{url}'>ici</a>."
new: new:
title: Nouveau fichier title: Nouveau fichier
help: "Vous avez le choix de soit uploader n'importe quel fichier ou bien soit de copier/coller du code css ou javascript." help: "Vous avez le choix de soit uploader n'importe quel fichier ou bien soit de copier/coller du code css ou javascript."
edit: edit:
title: "Edition {{file}}" title: "Edition %{file}"
help: "Vous pouvez utiliser ce fichier grâce a l'url suivante: {{url}}" help: "Vous pouvez utiliser ce fichier grâce a l'url suivante: %{url}"
form: form:
choose_file: Choisir fichier choose_file: Choisir fichier
choose_plain_text: Passer en mode texte choose_plain_text: Passer en mode texte
@ -207,7 +207,7 @@ fr:
title: Collections title: Collections
help: "Le nom de la collection est modifiable en cliquant dessus. Vous pouvez personnaliser une collection en ajoutant d'autres champs à vos médias." help: "Le nom de la collection est modifiable en cliquant dessus. Vous pouvez personnaliser une collection en ajoutant d'autres champs à vos médias."
new: nouvelle collection new: nouvelle collection
no_items: "Il n'existe pas de collections. Vous pouvez commencer par créer une <a href='{{url}}'>ici</a>." no_items: "Il n'existe pas de collections. Vous pouvez commencer par créer une <a href='%{url}'>ici</a>."
new: new:
title: Nouvelle collection title: Nouvelle collection
help: "Pour le moment, veuillez rentrer le nom. Les autres options viendront dans le formulaire suivant." help: "Pour le moment, veuillez rentrer le nom. Les autres options viendront dans le formulaire suivant."
@ -215,7 +215,7 @@ fr:
help: "Le nom de la collection est modifiable en cliquant dessus. Vous pouvez personnaliser une collection en ajoutant d'autres champs à vos médias." help: "Le nom de la collection est modifiable en cliquant dessus. Vous pouvez personnaliser une collection en ajoutant d'autres champs à vos médias."
add_asset: ajouter média add_asset: ajouter média
destroy: supprimer collection destroy: supprimer collection
no_items: "Il n'existe pas de médias. Vous pouvez commencer par créer un <a href='{{url}}'>ici</a>." no_items: "Il n'existe pas de médias. Vous pouvez commencer par créer un <a href='%{url}'>ici</a>."
ask_for_name: "Veuillez entrer le nouveau nom" ask_for_name: "Veuillez entrer le nouveau nom"
assets: assets:
@ -244,7 +244,7 @@ fr:
contents: contents:
index: index:
title: 'Liste des "{{type}}"' title: 'Liste des "%{type}"'
edit: éditer modèle edit: éditer modèle
destroy: supprimer modèle destroy: supprimer modèle
download: télécharger éléments download: télécharger éléments
@ -253,11 +253,11 @@ fr:
lastest_items: "Eléments récents" lastest_items: "Eléments récents"
updated_at: "Mis à jour le" updated_at: "Mis à jour le"
list: list:
no_items: "Il n'existe pas d'éléments. Vous pouvez commencer par créer un <a href='{{url}}'>ici</a>" no_items: "Il n'existe pas d'éléments. Vous pouvez commencer par créer un <a href='%{url}'>ici</a>"
new: new:
title: '{{type}} &mdash; nouvel élément' title: '%{type} &mdash; nouvel élément'
edit: edit:
title: '{{type}} &mdash; édition élément' title: '%{type} &mdash; édition élément'
image_picker: image_picker:
link: Insérer une image dans le code link: Insérer une image dans le code

View File

@ -5,13 +5,13 @@ en:
errors: errors:
messages: messages:
domain_taken: "{{value}} is already taken" domain_taken: "%{value} is already taken"
invalid_domain: "{{value}} is invalid" invalid_domain: "%{value} is invalid"
missing_content_for_layout: "should contain 'content_for_layout' liquid tag" missing_content_for_layout: "should contain 'content_for_layout' liquid tag"
needs_admin_account: "One admin account is required at least" needs_admin_account: "One admin account is required at least"
protected_page: "You can not remove index or 404 pages" protected_page: "You can not remove index or 404 pages"
extname_changed: "New file does not have the original extension" extname_changed: "New file does not have the original extension"
array_too_short: "is too small (minimum element number is {{count}})" array_too_short: "is too small (minimum element number is %{count})"
liquid_syntax_error: "Syntax error in page parts, please check the syntax" liquid_syntax_error: "Syntax error in page parts, please check the syntax"
attributes: attributes:

View File

@ -1,7 +1,7 @@
fr: fr:
errors: errors:
# The default format use in full error messages. # The default format use in full error messages.
format: "{{attribute}} {{message}}" format: "%{attribute} %{message}"
# The values :model, :attribute and :value are always available for interpolation # The values :model, :attribute and :value are always available for interpolation
# The value :count is available when applicable. Can be used for pluralization. # The value :count is available when applicable. Can be used for pluralization.
@ -13,26 +13,26 @@ fr:
accepted: "doit être accepté(e)" accepted: "doit être accepté(e)"
empty: "doit être rempli(e)" empty: "doit être rempli(e)"
blank: "doit être rempli(e)" blank: "doit être rempli(e)"
too_long: "est trop long (pas plus de {{count}} caractères)" too_long: "est trop long (pas plus de %{count} caractères)"
too_short: "est trop court (au moins {{count}} caractères)" too_short: "est trop court (au moins %{count} caractères)"
wrong_length: "ne fait pas la bonne longueur (doit comporter {{count}} caractères)" wrong_length: "ne fait pas la bonne longueur (doit comporter %{count} caractères)"
taken: "n'est pas disponible" taken: "n'est pas disponible"
not_a_number: "n'est pas un nombre" not_a_number: "n'est pas un nombre"
greater_than: "doit être supérieur à {{count}}" greater_than: "doit être supérieur à %{count}"
greater_than_or_equal_to: "doit être supérieur ou égal à {{count}}" greater_than_or_equal_to: "doit être supérieur ou égal à %{count}"
equal_to: "doit être égal à {{count}}" equal_to: "doit être égal à %{count}"
less_than: "doit être inférieur à {{count}}" less_than: "doit être inférieur à %{count}"
less_than_or_equal_to: "doit être inférieur ou égal à {{count}}" less_than_or_equal_to: "doit être inférieur ou égal à %{count}"
odd: "doit être impair" odd: "doit être impair"
even: "doit être pair" even: "doit être pair"
domain_taken: "{{value}} a été déjà pris" domain_taken: "%{value} a été déjà pris"
invalid_domain: "{{value}} n'est pas valide" invalid_domain: "%{value} n'est pas valide"
missing_content_for_layout: "doit contenir le tag liquid 'content_for_layout'" missing_content_for_layout: "doit contenir le tag liquid 'content_for_layout'"
needs_admin_account: "Un minimum d'un scompte admin est requis" needs_admin_account: "Un minimum d'un scompte admin est requis"
protected_page: "Vous ne pouvez pas supprimer les pages index et 404" protected_page: "Vous ne pouvez pas supprimer les pages index et 404"
extname_changed: "Nouveau fichier n'a pas l'extension original" extname_changed: "Nouveau fichier n'a pas l'extension original"
array_too_short: "est trop petit (le nombre minimum d'éléments est {{count}})" array_too_short: "est trop petit (le nombre minimum d'éléments est %{count})"
liquid_syntax_error: "Erreur de syntaxe dans les sections de page, veuillez vérifier la syntaxe" liquid_syntax_error: "Erreur de syntaxe dans les sections de page, veuillez vérifier la syntaxe"
attributes: attributes:
@ -133,35 +133,35 @@ fr:
less_than_x_seconds: less_than_x_seconds:
zero: "moins d'une seconde" zero: "moins d'une seconde"
one: "moins de 1 seconde" one: "moins de 1 seconde"
other: "moins de {{count}} secondes" other: "moins de %{count} secondes"
x_seconds: x_seconds:
one: "1 seconde" one: "1 seconde"
other: "{{count}} secondes" other: "%{count} secondes"
less_than_x_minutes: less_than_x_minutes:
zero: "moins d'une minute" zero: "moins d'une minute"
one: "moins de 1 minute" one: "moins de 1 minute"
other: "moins de {{count}} minutes" other: "moins de %{count} minutes"
x_minutes: x_minutes:
one: "1 minute" one: "1 minute"
other: "{{count}} minutes" other: "%{count} minutes"
about_x_hours: about_x_hours:
one: "environ une heure" one: "environ une heure"
other: "environ {{count}} heures" other: "environ %{count} heures"
x_days: x_days:
one: "1 jour" one: "1 jour"
other: "{{count}} jours" other: "%{count} jours"
about_x_months: about_x_months:
one: "environ un mois" one: "environ un mois"
other: "environ {{count}} mois" other: "environ %{count} mois"
x_months: x_months:
one: "1 mois" one: "1 mois"
other: "{{count}} mois" other: "%{count} mois"
about_x_years: about_x_years:
one: "environ un an" one: "environ un an"
other: "environ {{count}} ans" other: "environ %{count} ans"
over_x_years: over_x_years:
one: "plus d'un an" one: "plus d'un an"
other: "plus de {{count}} ans" other: "plus de %{count} ans"
prompts: prompts:
year: "Année" year: "Année"
month: "Mois" month: "Mois"

View File

@ -27,6 +27,7 @@ NICE TO HAVE:
- asset picker (content instance) - asset picker (content instance)
- page with regexp url ? - page with regexp url ?
- page redirection (option) - page redirection (option)
- automatic update !
DONE: DONE:

View File

@ -34,7 +34,6 @@ Capybara.default_selector = :css
ActionController::Base.allow_rescue = false ActionController::Base.allow_rescue = false
require 'factory_girl' require 'factory_girl'
require 'spec/factories'
Before do Before do
Mongoid.master.collections.select { |c| c.name != 'system.indexes' }.each(&:drop) Mongoid.master.collections.select { |c| c.name != 'system.indexes' }.each(&:drop)

View File

@ -21,7 +21,7 @@ module Locomotive
def liquify_template(source = :value) def liquify_template(source = :value)
field :serialized_template, :type => Binary field :serialized_template, :type => Binary
before_validate :store_template before_validation :store_template
class_eval <<-EOV class_eval <<-EOV
def liquify_template_source def liquify_template_source

View File

@ -3,66 +3,15 @@ require 'mongoid'
## various patches ## various patches
module Mongoid #:nodoc: module Mongoid #:nodoc:
# Enabling scope in validates_uniqueness_of validation
module Validations #:nodoc:
class UniquenessValidator < ActiveModel::EachValidator
def validate_each(document, attribute, value)
conditions = { attribute => value, :_id.ne => document._id }
if options.has_key?(:scope) && !options[:scope].nil?
[*options[:scope]].each do |scoped_attr|
conditions[scoped_attr] = document.attributes[scoped_attr]
end
end
return if document.class.where(conditions).empty?
document.errors.add(attribute, :taken, :default => options[:message], :value => value)
end
end
end
# FIX BUG #71 http://github.com/durran/mongoid/commit/47a97094b32448aa09965c854a24c78803c7f42e
module Associations
module InstanceMethods
def update_embedded(name)
association = send(name)
association.to_a.each { |doc| doc.save if doc.changed? || doc.new_record? } unless association.blank?
end
end
class EmbedsMany < Proxy
def nested_build(attributes, options = {})
deleted_indexes = []
attributes.each do |index, attrs|
if document = detect { |document| document._index == index.to_i }
if options && options[:allow_destroy] && attrs['_destroy']
deleted_indexes << document._index
@target.delete(document)
document.destroy
else
document.write_attributes(attrs)
document._index = index.to_i - deleted_indexes.collect { |i| i < index.to_i }.size
end
else
build(attrs)
end
end
end
end
end
# FIX BUG about accepts_nested_attributes_for
module Document module Document
module InstanceMethods
def remove(child) def update_child_with_noname(child, clear = false)
name = child.association_name name = child.association_name
@attributes.remove(name, child.raw_attributes) return if name.blank? # fix a weird bug with mongoid-acts-as-tree
end update_child_without_noname(child, clear)
end end
alias_method_chain :update_child, :noname
end end
end end

View File

@ -15,7 +15,7 @@ describe AssetCollection do
@collection = Factory.build(:asset_collection, :site => site) @collection = Factory.build(:asset_collection, :site => site)
@collection.asset_custom_fields.build :label => 'My Description', :_alias => 'description', :kind => 'Text' @collection.asset_custom_fields.build :label => 'My Description', :_alias => 'description', :kind => 'Text'
@collection.asset_custom_fields.build :label => 'Active', :kind => 'Boolean' @collection.asset_custom_fields.build :label => 'Active', :kind => 'Boolean'
# AssetCollection.collection.logger = Logger.new($stdout) # AssetCollection.logger = Logger.new($stdout)
# AssetCollection.db.connection.instance_variable_set(:@logger, Logger.new($stdout)) # AssetCollection.db.connection.instance_variable_set(:@logger, Logger.new($stdout))
end end
@ -143,7 +143,7 @@ describe AssetCollection do
context 'managing from hash' do context 'managing from hash' do
it 'should add new field' do it 'adds new field' do
@collection.asset_custom_fields.clear @collection.asset_custom_fields.clear
@collection.asset_custom_fields.build :label => 'Title' @collection.asset_custom_fields.build :label => 'Title'
@collection.asset_custom_fields_attributes = { '0' => { 'label' => 'A title', 'kind' => 'String' }, '-1' => { 'label' => 'Tagline', 'kind' => 'String' } } @collection.asset_custom_fields_attributes = { '0' => { 'label' => 'A title', 'kind' => 'String' }, '-1' => { 'label' => 'Tagline', 'kind' => 'String' } }
@ -152,12 +152,12 @@ describe AssetCollection do
@collection.asset_custom_fields.last.label.should == 'Tagline' @collection.asset_custom_fields.last.label.should == 'Tagline'
end end
it 'should update/remove fields' do it 'updates/removes fields' do
@collection.asset_custom_fields.build :label => 'Title', :kind => 'String' @collection.asset_custom_fields.build :label => 'Title', :kind => 'String'
@collection.save; @collection = AssetCollection.first @collection.save; @collection = AssetCollection.first
@collection.update_attributes(:asset_custom_fields_attributes => { @collection.update_attributes(:asset_custom_fields_attributes => {
'0' => { 'label' => 'My Description', 'kind' => 'Text', '_destroy' => "1" }, '0' => { 'label' => 'My Description', 'kind' => 'Text', '_destroy' => '1' },
'1' => { 'label' => 'Active', 'kind' => 'Boolean', '_destroy' => "0" }, '1' => { 'label' => 'Active', 'kind' => 'Boolean', '_destroy' => '0' },
'2' => { 'label' => 'My Title !', 'kind' => 'String' }, '2' => { 'label' => 'My Title !', 'kind' => 'String' },
'new_record' => { 'label' => 'Published at', 'kind' => 'String' } 'new_record' => { 'label' => 'Published at', 'kind' => 'String' }
}) })

View File

@ -22,7 +22,7 @@ describe Layout do
it 'should have 2 parts' do it 'should have 2 parts' do
@layout.send(:build_parts_from_value) @layout.send(:build_parts_from_value)
@layout.parts.count.should == 2 @layout.parts.size.should == 2
@layout.parts.first.name.should == 'Body' @layout.parts.first.name.should == 'Body'
@layout.parts.first.slug.should == 'layout' @layout.parts.first.slug.should == 'layout'

View File

@ -2,8 +2,8 @@ source 'http://gemcutter.org'
gem 'bson_ext', '>= 1.0.1' gem 'bson_ext', '>= 1.0.1'
gem 'mongo_ext' gem 'mongo_ext'
gem 'mongoid', '2.0.0.beta6' gem 'mongoid-locomotive'
gem 'activesupport', '3.0.0.beta3' gem 'activesupport', '~>3.0.0.beta'
gem 'carrierwave-rails3', :require => 'carrierwave' gem 'carrierwave-rails3', :require => 'carrierwave'
group :test do group :test do

View File

@ -3,9 +3,9 @@ $:.unshift File.expand_path(File.dirname(__FILE__))
require 'active_support' require 'active_support'
require 'carrierwave/orm/mongoid' require 'carrierwave/orm/mongoid'
require 'custom_fields/extensions/mongoid/document' require 'custom_fields/extensions/mongoid/hierarchy'
require 'custom_fields/extensions/mongoid/associations/proxy' require 'custom_fields/extensions/mongoid/associations/proxy'
require 'custom_fields/extensions/mongoid/associations/has_many_related' require 'custom_fields/extensions/mongoid/associations/references_many'
require 'custom_fields/extensions/mongoid/associations/embeds_many' require 'custom_fields/extensions/mongoid/associations/embeds_many'
require 'custom_fields/types/default' require 'custom_fields/types/default'
require 'custom_fields/types/string' require 'custom_fields/types/string'

View File

@ -20,7 +20,7 @@ module CustomFields
# #
# company.employee_custom_fields.build :label => 'His/her position', :_alias => 'position', :kind => 'String' # company.employee_custom_fields.build :label => 'His/her position', :_alias => 'position', :kind => 'String'
# #
# company.employees.build :name => 'Mickael Scott', :position => 'Regional manager' # company.employees.build :name => 'Michael Scott', :position => 'Regional manager'
# #
module ClassMethods module ClassMethods

View File

@ -3,7 +3,7 @@ module Mongoid #:nodoc:
module Associations #:nodoc: module Associations #:nodoc:
# Represents an relational one-to-many association with an object in a # Represents an relational one-to-many association with an object in a
# separate collection or database. # separate collection or database.
class HasManyRelated < Proxy class ReferencesMany < Proxy
def initialize_with_custom_fields(parent, options, target_array = nil) def initialize_with_custom_fields(parent, options, target_array = nil)
if custom_fields?(parent, options.name) if custom_fields?(parent, options.name)

View File

@ -1,6 +1,6 @@
# encoding: utf-8 # encoding: utf-8
module Mongoid #:nodoc: module Mongoid #:nodoc
module Document module Hierarchy #:nodoc
module InstanceMethods module InstanceMethods
def parentize_with_custom_fields(object, association_name) def parentize_with_custom_fields(object, association_name)

View File

@ -87,7 +87,7 @@ describe CustomFields::CustomFieldsFor do
end end
it 'returns a new document whose Class is different from the original one' do it 'returns a new document whose Class is different from the original one' do
@person.class.should_not == Task @person.class.should_not == Person
end end
it 'returns a new document with custom field' do it 'returns a new document with custom field' do