From bbd8478d795dff4969369cc96aa68d7dfbad868d Mon Sep 17 00:00:00 2001 From: Cairo Noleto Date: Wed, 13 Jun 2012 09:16:10 -0300 Subject: [PATCH 1/2] Minor refactoring --- lib/i18n_alchemy/proxy.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/i18n_alchemy/proxy.rb b/lib/i18n_alchemy/proxy.rb index bfdbad1..64abc1a 100644 --- a/lib/i18n_alchemy/proxy.rb +++ b/lib/i18n_alchemy/proxy.rb @@ -53,12 +53,11 @@ def method_missing(*args, &block) private def active_record_compatible? - target_class = @target.class target_class.respond_to?(:columns) && target_class.respond_to?(:nested_attributes_options) end def build_attributes - @target.class.columns.each do |column| + columns.each do |column| column_name = column.name next if column.primary || column_name.ends_with?("_id") || @localized_attributes.key?(column_name) @@ -68,7 +67,7 @@ def build_attributes end def build_methods - @target.class.localized_methods.each_pair do |method, parser_type| + localized_methods.each_pair do |method, parser_type| method = method.to_s parser = detect_parser(parser_type) build_attribute(method, parser) @@ -133,6 +132,18 @@ def detect_parser(type_or_parser) type_or_parser end end + + def localized_methods + target_class.localized_methods + end + + def columns + target_class.columns + end + + def target_class + @target.class + end end end end From 64208535e05d418e0d03b5f74e628e12e00071ea Mon Sep 17 00:00:00 2001 From: Cairo Noleto Date: Wed, 13 Jun 2012 09:19:18 -0300 Subject: [PATCH 2/2] Adding support to custom association parser. With this, we fix #18. --- lib/i18n_alchemy/proxy.rb | 19 ++++++++++++++----- .../my_custom_association_parser.rb | 13 +++++++++++++ test/db/test_schema.rb | 10 ++++++++++ .../proxy/attributes_parsing_test.rb | 8 ++++++++ test/models/company.rb | 3 +++ test/models/person.rb | 16 ++++++++++++++++ test/test_helper.rb | 2 ++ 7 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 test/custom_parsers/my_custom_association_parser.rb create mode 100644 test/models/company.rb create mode 100644 test/models/person.rb diff --git a/lib/i18n_alchemy/proxy.rb b/lib/i18n_alchemy/proxy.rb index 64abc1a..bf1e3c3 100644 --- a/lib/i18n_alchemy/proxy.rb +++ b/lib/i18n_alchemy/proxy.rb @@ -75,8 +75,8 @@ def build_methods end def build_associations - @target.class.nested_attributes_options.each_key do |association_name| - create_localized_association(association_name) + nested_attributes_options.each_key do |association_name| + create_localized_association(association_name, detect_parser_from_association(association_name)) end end @@ -86,9 +86,8 @@ def build_attribute(name, parser) define_localized_methods(name) end - def create_localized_association(association_name) - @localized_associations << - AssociationParser.new(@target.class, association_name) + def create_localized_association(association_name, parser) + @localized_associations << parser.new(target_class, association_name) end def create_localized_attribute(column_name, parser) @@ -120,6 +119,10 @@ def detect_parser_from_column(column) detect_parser(column.number? ? :number : column.type) end + def detect_parser_from_association(association_name) + detect_parser(localized_methods[association_name] ? localized_methods[association_name] : :association) + end + def detect_parser(type_or_parser) case type_or_parser when :number @@ -128,6 +131,8 @@ def detect_parser(type_or_parser) DateParser when :datetime, :timestamp TimeParser + when :association + AssociationParser when ::Module type_or_parser end @@ -141,6 +146,10 @@ def columns target_class.columns end + def nested_attributes_options + target_class.nested_attributes_options + end + def target_class @target.class end diff --git a/test/custom_parsers/my_custom_association_parser.rb b/test/custom_parsers/my_custom_association_parser.rb new file mode 100644 index 0000000..9b278c6 --- /dev/null +++ b/test/custom_parsers/my_custom_association_parser.rb @@ -0,0 +1,13 @@ +class MyCustomAssociationParser < I18n::Alchemy::AssociationParser + def parse(attributes) + if association.options[:polymorphic] + @proxy = target_class.i18n_alchemy_proxy.localized + end + + super + end + + def self.localize(object) + object + end +end diff --git a/test/db/test_schema.rb b/test/db/test_schema.rb index 5fb6583..c57bbd3 100644 --- a/test/db/test_schema.rb +++ b/test/db/test_schema.rb @@ -27,4 +27,14 @@ t.string :account_number t.decimal :total_money end + + create_table :people do |t| + t.string :name + t.integer :personable_id + t.string :personable_type + end + + create_table :companies do |t| + t.string :register + end end diff --git a/test/i18n_alchemy/proxy/attributes_parsing_test.rb b/test/i18n_alchemy/proxy/attributes_parsing_test.rb index 2fd773f..3ed9077 100644 --- a/test/i18n_alchemy/proxy/attributes_parsing_test.rb +++ b/test/i18n_alchemy/proxy/attributes_parsing_test.rb @@ -29,6 +29,8 @@ def test_assign_attributes end def test_mass_assigning_invalid_attribute + @person = Person.new + @person_localized = @person.localized assert_raises(ActiveRecord::UnknownAttributeError) do @localized.assign_attributes('i_dont_even_exist' => 40) end @@ -128,6 +130,12 @@ def test_attributes_assignment_for_nested assert_equal '88,12', @supplier_localized.account.localized.total_money end + def test_should_assign_for_nested_attributes_for_polymorphic_association + @person_localized.assign_attributes(:personable_type => "Company", :personable_attributes => {:register => 10}) + company = @person_localized.personable + assert_equal 10, company.register + end + private def attributes_hash diff --git a/test/models/company.rb b/test/models/company.rb new file mode 100644 index 0000000..10a4e41 --- /dev/null +++ b/test/models/company.rb @@ -0,0 +1,3 @@ +class Company < ActiveRecord::Base + include I18n::Alchemy +end diff --git a/test/models/person.rb b/test/models/person.rb new file mode 100644 index 0000000..4df4cb6 --- /dev/null +++ b/test/models/person.rb @@ -0,0 +1,16 @@ +class Person < ActiveRecord::Base + include I18n::Alchemy + localize :personable, :using => MyCustomAssociationParser + + belongs_to :personable, :polymorphic => true + + accepts_nested_attributes_for :personable + + def build_personable(attributes, options = {}) + self.personable = personable_type.constantize.new(attributes, options) + end + + def self.i18n_alchemy_proxy + Company.new + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index fd7cd8e..5c72e93 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -36,6 +36,8 @@ def setup @supplier_localized = @supplier.localized @user = User.new @user_localized = @user.localized + @person = Person.new + @person_localized = @person.localized I18n.locale = :pt end