From 277b5314490aa449e69fbd67ea9a5351c9c8deba Mon Sep 17 00:00:00 2001 From: dinedine Date: Tue, 18 May 2010 00:51:53 +0200 Subject: [PATCH] first draft of custom fields --- app/models/asset_collection.rb | 3 + app/models/asset_field.rb | 25 ++--- config/initializers/custom_fields.rb | 6 +- doc/TODO | 3 +- spec/models/asset_collections_spec.rb | 143 +++++++++++++------------- 5 files changed, 88 insertions(+), 92 deletions(-) diff --git a/app/models/asset_collection.rb b/app/models/asset_collection.rb index 80b6dae5..ed0e264e 100644 --- a/app/models/asset_collection.rb +++ b/app/models/asset_collection.rb @@ -14,6 +14,9 @@ class AssetCollection embeds_many :asset_fields # FIXME (custom fields) + ## behaviours ## + accepts_nested_attributes_for :asset_fields # FIXME (custom fields) + ## callbacks ## before_validate :normalize_slug before_save :store_asset_positions! diff --git a/app/models/asset_field.rb b/app/models/asset_field.rb index b04c3f9c..010ad4d5 100644 --- a/app/models/asset_field.rb +++ b/app/models/asset_field.rb @@ -8,15 +8,7 @@ class AssetField field :_name, :type => String field :kind, :type => String field :position, :type => Integer, :default => 0 - - ## associations ## - embedded_in :collection, :class_name => 'AssetCollection', :inverse_of => :asset_fields - - ## callbacks ## - before_save :set_alias - # before_create :add_to_list_bottom => FIXME _index does the trick actually - # before_save :set_unique_name! - + ## validations ## validates_presence_of :label, :kind @@ -31,18 +23,20 @@ class AssetField end def apply(object, association_name) - puts "applying...#{self._name} / #{self._alias}" + # puts "applying...#{self._name} / #{self._alias}" object.class.send(:set_field, self._name, { :type => self.field_type }) object.class_eval <<-EOF - alias :#{self._alias} :#{self._name} + alias :#{self.safe_alias} :#{self._name} + alias :#{self.safe_alias}= :#{self._name}= EOF end - protected + def safe_alias + self.set_alias + self._alias + end - # def add_to_list_bottom - # self.position = (self.siblings.map(&:position).max || 0) + 1 - # end + protected def set_unique_name! self._name = "custom_field_#{self.increment_counter!}" @@ -50,7 +44,6 @@ class AssetField def set_alias return if self.label.blank? && self._alias.blank? - puts "set_alias !!!" self._alias ||= self.label.clone self._alias.slugify!(:downcase => true, :underscore => true) end diff --git a/config/initializers/custom_fields.rb b/config/initializers/custom_fields.rb index 4afded8c..041439b1 100644 --- a/config/initializers/custom_fields.rb +++ b/config/initializers/custom_fields.rb @@ -25,6 +25,8 @@ module Mongoid #:nodoc: alias_method_chain :build, :custom_field_settings def target_custom_field_association? + return unless @association_name.ends_with?('_fields') + target_name = @association_name.gsub(/_fields$/, '').pluralize # puts "target_name = #{target_name} / #{@parent.associations.key?(target_name).inspect} / #{@parent.inspect} / #{@parent.associations.inspect}" if @parent.associations.key?(target_name) @@ -47,13 +49,13 @@ module Mongoid #:nodoc: if self.custom_fields?(object, association_name) # puts "custom fields = #{object.asset_fields.inspect}" - puts "((((((((" + # puts "((((((((" object.send(self.custom_fields_association_name(association_name)).each do |field| # puts "field = #{field.inspect}" # self.class.send(:set_field, field.name, { :type => field.field_type }) field.apply(self, association_name) end - puts "))))))))" + # puts "))))))))" end end diff --git a/doc/TODO b/doc/TODO index 597e0987..969225ff 100644 --- a/doc/TODO +++ b/doc/TODO @@ -50,12 +50,13 @@ x domain scoping when authenticating - assets uploader: - remove old files if new one - custom fields: - - renaming fields + x renaming fields - ui - rename asset_field - apply in asset_field - extract a plugin from custom fields - field position + - nested attributes BACKLOG: - liquid rendering engine diff --git a/spec/models/asset_collections_spec.rb b/spec/models/asset_collections_spec.rb index e89400d1..f66a2938 100644 --- a/spec/models/asset_collections_spec.rb +++ b/spec/models/asset_collections_spec.rb @@ -2,98 +2,95 @@ require 'spec_helper' describe AssetCollection do - it 'should have a valid factory' do - Factory.build(:asset_collection).should be_valid - end + # it 'should have a valid factory' do + # Factory.build(:asset_collection).should be_valid + # end describe 'custom fields (beta)' do before(:each) do - @collection = Factory.build(:asset_collection) + @collection = Factory.build(:asset_collection, :site => nil) @collection.asset_fields.build :label => 'My Description', :_alias => 'description', :kind => 'Text' @collection.asset_fields.build :label => 'Active', :kind => 'Boolean' end - context 'define attributes' do + context 'define core attributes' do - # it 'should have an unique name' do - # @collection.asset_fields.first._name.should == "custom_field_1" - # @collection.asset_fields.last._name.should == "custom_field_2" - # end + it 'should have an unique name' do + @collection.asset_fields.first._name.should == "custom_field_1" + @collection.asset_fields.last._name.should == "custom_field_2" + end it 'should have an unique alias' do - @collection.save @collection.asset_fields.first._alias.should == "description" @collection.asset_fields.last._alias.should == "active" end - - # - # it 'should define a position according to siblings' - + + end + + context 'build and save' do + + it 'should build asset' do + asset = @collection.assets.build + lambda { + asset.description + asset.active + }.should_not raise_error + end + + it 'should assign values to newly built asset' do + asset = build_asset(@collection) + asset.description.should == 'Lorem ipsum' + asset.active.should == true + end + + it 'should save asset' do + asset = build_asset(@collection) + asset.save and @collection.reload + asset = @collection.assets.first + asset.description.should == 'Lorem ipsum' + asset.active.should == true + end + + it 'should not modify assets from another collection' do + asset = build_asset(@collection) + asset.save and @collection.reload + new_collection = AssetCollection.new + lambda { new_collection.assets.build.description }.should raise_error + end + end - # context 'build and save' do - # - # it 'should build asset' do - # asset = @collection.assets.build - # lambda { - # asset.description - # asset.active - # }.should_not raise_error - # end - # - # it 'should assign values to newly built asset' do - # asset = build_asset(@collection) - # asset.description.should == 'Lorem ipsum' - # asset.active.should == true - # end - # - # it 'should save asset' do - # asset = build_asset(@collection) - # asset.save and @collection.reload - # asset = @collection.assets.first - # asset.description.should == 'Lorem ipsum' - # asset.active.should == true - # end - # - # it 'should not modify assets from another collection' do - # asset = build_asset(@collection) - # asset.save and @collection.reload - # new_collection = AssetCollection.new - # lambda { new_collection.assets.build.description }.should raise_error - # end - # - # end - # context 'modifying fields' do - # before(:each) do - # @asset = build_asset(@collection).save - # end - # - # it 'should add new field' do - # @collection.asset_fields.build :label => 'Active at', :name => 'active_at', :kind => 'Date' - # @collection.save - # - # # puts "association = #{@collection.send(:associations)['assets'].options.inspect}" - # - # # @collection = AssetCollection.first - # # @collection.flush_cache(:asset_fields) - # @collection.reload - # # puts "# fields #{@collection.asset_fields.size.inspect}" - # # puts "============================" - # # puts "@collection asset fields ==> #{@collection.asset_fields.inspect}" - # asset = @collection.assets.first - # lambda { asset.active_at }.should_not raise_error - # end + before(:each) do + @asset = build_asset(@collection).save + end - # it 'should remove field' do - # @collection.asset_fields.delete_all :name => 'active' - # @collection.save - # lambda { asset.active }.should raise_error - # end - # - # it 'should be able to change field name' + it 'should add new field' do + @collection.asset_fields.build :label => 'Active at', :name => 'active_at', :kind => 'Date' + @collection.upsert(false) + @collection.reload + asset = @collection.assets.first + lambda { asset.active_at }.should_not raise_error + end + + it 'should remove field' do + @collection.asset_fields.clear + @collection.upsert(false) + @collection.reload + asset = @collection.assets.first + lambda { asset.active }.should raise_error + end + + it 'should rename field label' do + @collection.asset_fields.first.label = 'Simple description' + @collection.asset_fields.first._alias = nil + @collection.upsert(false) + @collection.reload + asset = @collection.assets.first + asset.simple_description.should == 'Lorem ipsum' + end end