Skip to content
Permalink
Browse files

Adding ability to specify the key's class, rather than always assume …

…String. Useful for fields that have multiple values and need to be saved as an Array.
  • Loading branch information...
Walter McGinnis
Walter McGinnis committed Jan 12, 2011
1 parent fabf73b commit 767d8d9b21b6aa7a25d849e01eb9f392c8118454
@@ -84,10 +84,21 @@ def mongo_translate(*args)
cattr_accessor :translatable_class
self.translatable_class = self.name.split('::').first.constantize

self.translatable_class.translatable_attributes.each do |translatable_attribute|
key translatable_attribute, String
def self.declare_key_from(spec)
key_type = String
key_name = spec

key_name, key_type = spec if spec.is_a?(Array)

unless keys.include?(key_name.to_s)
class_eval do
key key_name, key_type
end
end
end

self.translatable_class.translatable_attributes.each { |a| declare_key_from(a) }

key :locale, String, :required => true

before_save :locale_to_string
@@ -96,13 +107,9 @@ def mongo_translate(*args)
# add definition of keys for mongo_translatable Translation class, if not already defined
# add accessor methods, too, if not already defined
def self.update_keys_if_necessary_with(new_translatable_attributes)
new_translatable_attributes.each do |attribute|
unless keys.include?(attribute.to_s)
class_eval do
key attribute, String
end
end
end
attribute_type = String

new_translatable_attributes.each { |a| declare_key_from(a) }
end

# TODO: add validation for locale unique to translatable_class.as_foreign_key_sym scope
@@ -0,0 +1,21 @@
class Recipe < ActiveRecord::Base
# mongo_translate :name, :ingredients, :steps
mongo_translate :name, [:ingredients, Array], [:steps, Array]

def steps=(value)
super(YAML.dump(value))
end

def ingredients=(value)
super(YAML.dump(value))
end

def steps
YAML.load(super)
end

def ingredients
YAML.load(super)
end

end
@@ -0,0 +1,14 @@
class CreateRecipes < ActiveRecord::Migration
def self.up
create_table :recipes do |t|
t.string :name, :locale, :original_locale, :null => false
t.text :ingredients, :steps, :null => false

t.timestamps
end
end

def self.down
drop_table :recipes
end
end
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20100509042718) do
ActiveRecord::Schema.define(:version => 20110112023516) do

create_table "comments", :force => true do |t|
t.string "subject"
@@ -43,4 +43,14 @@
t.datetime "updated_at"
end

create_table "recipes", :force => true do |t|
t.string "name", :null => false
t.string "locale", :null => false
t.string "original_locale", :null => false
t.text "ingredients", :null => false
t.text "steps", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end

end
@@ -10,3 +10,9 @@
Factory.define :person do |p|
p.sequence(:name) { |n| "a name#{n}"}
end

Factory.define :recipe do |r|
r.sequence(:name) { |n| "a name#{n}"}
r.sequence(:steps) { |n| ["steps#{n} - 1", "steps#{n} - 2"]}
r.sequence(:ingredients) { |n| ["ingredients#{n} - 1", "ingredients#{n} - 2"]}
end
@@ -259,6 +259,45 @@ class MongodbTranslatableTest < ActiveSupport::TestCase
end
end

context "A Translatable class that has some translatable_attributes with key_type specified" do

should "have String for type of key without key_type specified (default)" do
assert_equal Recipe::Translation.keys['name'].type, String
end

should "have Array for type of key when " do
assert_equal Recipe::Translation.keys['steps'].type, Array
assert_equal Recipe::Translation.keys['ingredients'].type, Array
end

context "can create translations that" do
setup do
I18n.locale = I18n.default_locale
@recipe = Factory.create(:recipe)
end

should "return value in correct key type for translatable_attribute" do
assert_equal @recipe.steps, ["steps1 - 1", "steps1 - 2"]
assert_equal @recipe.ingredients, ["ingredients1 - 1", "ingredients1 - 2"]

fr_steps = ['fr step 1', 'fr step 2']
fr_ingredients = ['fr ingredient 1', 'fr ingredient 2']

@recipe_translation = @recipe.class::Translation.create(:name => @recipe.attributes['name'],
:steps => fr_steps,
:ingredients => fr_ingredients,
:locale => :fr,
@recipe.class.as_foreign_key_sym => @recipe.id)

@recipe_translation.reload

assert_equal fr_steps, @recipe_translation.steps
assert_equal fr_ingredients, @recipe_translation.ingredients
end

end
end

private

# see many_tests for what it expects

0 comments on commit 767d8d9

Please sign in to comment.
You can’t perform that action at this time.