to_hash method of content entries does not work well with i18n fields (fixing it)

did committed Oct 08, 2015
commit d36c12ecb858484479c8018662661e6bb470d141
Showing 5 changed files with 59 additions and 6 deletions
locomotive/steam/decorators/i18n_decorator.rb b/lib/locomotive/steam/decorators/i18n_decorator.rb +1 -0
@@ @@ -86,6 +86,7 @@ module Locomotive
def to_hash
__getobj__.to_hash.tap do |hash|
+ puts @__localized_attributes__.inspect
@__localized_attributes__.keys.each do |name|
hash[name.to_s] = __get_localized_value__(name)
end
locomotive/steam/entities/content_entry.rb b/lib/locomotive/steam/entities/content_entry.rb +15 -2
@@ @@ -84,7 +84,20 @@ module Locomotive::Steam
hash['content_type_slug'] = self.content_type_slug
content_type.fields_by_name.each do |name, field|
- hash[name] = _cast_value(field)
+ value = send(field.name)
+
+ # custom behaviors for some types
+ case field.type
+ when :belongs_to
+ # TODO
+ when :many_to_many
+ # TODO
+ when :file
+ puts "value = #{value.inspect}"
+ hash[name] = hash[:"#{name}_url"] = value.respond_to?(:transform!) ? value.transform!(&:url) : value.url
+ else
+ hash[name] = value
+ end
end
end
end
@@ @@ -128,7 +141,7 @@ module Locomotive::Steam
def _cast_file(field)
_cast_convertor(field.name) do |value|
- FileField.new(value, base_url, self.updated_at)
+ value.respond_to?(:url) ? value : FileField.new(value, self[:base_url], self.updated_at)
end
end
locomotive/steam/models/i18n_field.rb b/lib/locomotive/steam/models/i18n_field.rb +15 -0
@@ @@ -14,6 +14,11 @@ module Locomotive::Steam
self.translations = translations
end
+ def initialize_copy(field)
+ super
+ self.translations = field.translations.dup
+ end
+
def [](locale)
@translations[locale]
end
@@ @@ -42,6 +47,16 @@ module Locomotive::Steam
attributes[@name] = @translations
end
+ def transform
+ @translations.each do |locale, value|
+ @translations[locale] = yield(value)
+ end
+ end
+
+ def transform!(&block)
+ self.dup.tap { |field| field.transform(&block) }
+ end
+
end
end
spec/unit/entities/content_entry_spec.rb +16 -4
@@ @@ -57,16 +57,28 @@ describe Locomotive::Steam::ContentEntry do
describe '#to_hash' do
- let(:fields) { [instance_double('Field', name: :title, type: :string, required: true)] }
- let(:attributes) { { id: 42, title: 'Hello world', _slug: 'hello-world', custom_fields_recipe: ['hello', 'world'], _type: 'Entry' } }
+ let(:fields) { [instance_double('TitleField', name: :title, type: :string), instance_double('PictureField', name: :picture, type: :file, localized: true)] }
+ let(:attributes) { { id: 42, title: 'Hello world', _slug: 'hello-world', picture: Locomotive::Steam::Models::I18nField.new(:picture, fr: 'foo.png', en: 'bar.png'), base_url: '/assets', custom_fields_recipe: ['hello', 'world'], _type: 'Entry' } }
subject { content_entry.to_hash }
before do
- allow(type).to receive(:fields_by_name).and_return({ title: fields.first })
+ allow(type).to receive(:fields_by_name).and_return({ title: fields.first, picture: fields.last })
end
- it { expect(Set.new(subject.keys)).to eq(Set.new(['id', '_id', '_position', '_visible', '_label', '_slug', 'content_type_slug', 'title', 'created_at', 'updated_at'])) }
+ it { expect(Set.new(subject.keys)).to eq(Set.new(['id', '_id', '_position', '_visible', '_label', '_slug', 'content_type_slug', 'title', 'picture_url', 'picture', 'created_at', 'updated_at'])) }
+
+ context 'when decorated' do
+
+ let(:decorated) { Locomotive::Steam::Decorators::I18nDecorator.new(content_entry, :fr, :en) }
+
+ before { allow(content_entry).to receive(:localized_attributes).and_return({ picture: true }) }
+
+ subject { puts decorated.picture.inspect; puts decorated.send(:picture).inspect; puts "---"; decorated.to_hash }
+
+ it { expect(subject[:picture]).to eq '/assets/foo.png' }
+
+ end
end
spec/unit/models/i18n_field_spec.rb +12 -0
@@ @@ -22,4 +22,16 @@ describe Locomotive::Steam::Models::I18nField do
end
+ describe '#transform' do
+
+ let(:translations) { { fr: 42, en: '42' } }
+
+ before { field.transform(&:to_s) }
+
+ subject { field.translations }
+
+ it { is_expected.to eq('fr' => '42', 'en' => '42') }
+
+ end
+
end