From 7171f603f86b71d48d6a7cf2652ce75e3439bff0 Mon Sep 17 00:00:00 2001 From: dinedine Date: Fri, 21 May 2010 02:34:32 +0200 Subject: [PATCH] refactoring of CustomField plugin in progress (cleaned a lot) --- app/models/asset_collection.rb | 8 +-- app/models/asset_field.rb | 2 +- spec/models/asset_collections_spec.rb | 42 ++++++------- .../custom_fields/lib/custom_fields.rb | 1 - .../lib/custom_fields/custom_field.rb | 63 +++++++++++++++++++ .../lib/custom_fields/custom_fields_for.rb | 9 ++- .../mongoid/associations/embeds_many.rb | 19 +++--- .../mongoid/associations/options.rb | 10 --- .../extensions/mongoid/document.rb | 5 +- 9 files changed, 105 insertions(+), 54 deletions(-) create mode 100644 vendor/plugins/custom_fields/lib/custom_fields/custom_field.rb delete mode 100644 vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/options.rb diff --git a/app/models/asset_collection.rb b/app/models/asset_collection.rb index a1f4908f..272d7db5 100644 --- a/app/models/asset_collection.rb +++ b/app/models/asset_collection.rb @@ -6,19 +6,19 @@ class AssetCollection ## fields ## field :name, :type => String field :slug, :type => String - field :asset_fields_counter, :type => Integer, :default => 0 # FIXME (custom fields) + # field :asset_fields_counter, :type => Integer, :default => 0 # FIXME (custom fields) ## associations ## belongs_to_related :site - embeds_many :assets, :custom_fields => true + embeds_many :assets #, :custom_fields => true # FIXME (custom fields) - embeds_many :asset_fields # FIXME (custom fields) + # embeds_many :asset_fields # FIXME (custom fields) ## behaviours ## custom_fields_for :assets - accepts_nested_attributes_for :asset_fields, :allow_destroy => true # FIXME (custom fields) + # accepts_nested_attributes_for :asset_fields, :allow_destroy => true # FIXME (custom fields) ## callbacks ## before_validate :normalize_slug diff --git a/app/models/asset_field.rb b/app/models/asset_field.rb index 8b2a8db9..dd31fa8f 100644 --- a/app/models/asset_field.rb +++ b/app/models/asset_field.rb @@ -12,7 +12,7 @@ class AssetField ## validations ## validates_presence_of :label, :kind - embedded_in :asset_collection, :inverse_of => :asset_fields + embedded_in :asset_collection, :inverse_of => :asset_custom_fields ## methods ## diff --git a/spec/models/asset_collections_spec.rb b/spec/models/asset_collections_spec.rb index 5f45661f..9719d9b6 100644 --- a/spec/models/asset_collections_spec.rb +++ b/spec/models/asset_collections_spec.rb @@ -10,21 +10,21 @@ describe AssetCollection do before(:each) do @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' - puts "first field index = #{@collection.asset_fields.first._index}" + @collection.asset_custom_fields.build :label => 'My Description', :_alias => 'description', :kind => 'Text' + @collection.asset_custom_fields.build :label => 'Active', :kind => 'Boolean' + puts "first field index = #{@collection.asset_custom_fields.first._index}" end 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" + @collection.asset_custom_fields.first._name.should == "custom_field_1" + @collection.asset_custom_fields.last._name.should == "custom_field_2" end it 'should have an unique alias' do - @collection.asset_fields.first._alias.should == "description" - @collection.asset_fields.last._alias.should == "active" + @collection.asset_custom_fields.first._alias.should == "description" + @collection.asset_custom_fields.last._alias.should == "active" end end @@ -69,7 +69,7 @@ describe AssetCollection do end it 'should add new field' do - @collection.asset_fields.build :label => 'Active at', :name => 'active_at', :kind => 'Date' + @collection.asset_custom_fields.build :label => 'Active at', :name => 'active_at', :kind => 'Date' @collection.upsert(false) @collection.reload asset = @collection.assets.first @@ -77,7 +77,7 @@ describe AssetCollection do end it 'should remove field' do - @collection.asset_fields.clear + @collection.asset_custom_fields.clear @collection.upsert(false) @collection.reload asset = @collection.assets.first @@ -85,8 +85,8 @@ describe AssetCollection do end it 'should rename field label' do - @collection.asset_fields.first.label = 'Simple description' - @collection.asset_fields.first._alias = nil + @collection.asset_custom_fields.first.label = 'Simple description' + @collection.asset_custom_fields.first._alias = nil @collection.upsert(false) @collection.reload asset = @collection.assets.first @@ -104,25 +104,25 @@ describe AssetCollection do end it 'should add new field' do - @collection.asset_fields.clear - @collection.asset_fields.build :label => 'Title' - @collection.asset_fields_attributes = { '0' => { 'label' => 'A title', 'kind' => 'String' }, '-1' => { 'label' => 'Tagline', 'kind' => 'String' } } - @collection.asset_fields.size.should == 2 - @collection.asset_fields.first.label.should == 'A title' - @collection.asset_fields.last.label.should == 'Tagline' + @collection.asset_custom_fields.clear + @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.size.should == 2 + @collection.asset_custom_fields.first.label.should == 'A title' + @collection.asset_custom_fields.last.label.should == 'Tagline' end it 'should update/remove fields' do - @collection.asset_fields.build :label => 'Title', :kind => 'String' + @collection.asset_custom_fields.build :label => 'Title', :kind => 'String' @collection.save; @collection = AssetCollection.first - @collection.update_attributes(:asset_fields_attributes => { + @collection.update_attributes(:asset_custom_fields_attributes => { '0' => { 'label' => 'My Description', 'kind' => 'Text', '_destroy' => "1" }, '1' => { 'label' => 'Active', 'kind' => 'Boolean', '_destroy' => "0" }, '2' => { 'label' => 'My Title !', 'kind' => 'String' } }) @collection = AssetCollection.first - @collection.asset_fields.size.should == 1 - @collection.asset_fields.first.label.should == 'My Title !' + @collection.asset_custom_fields.size.should == 1 + @collection.asset_custom_fields.first.label.should == 'My Title !' end end diff --git a/vendor/plugins/custom_fields/lib/custom_fields.rb b/vendor/plugins/custom_fields/lib/custom_fields.rb index ca506184..f0197940 100644 --- a/vendor/plugins/custom_fields/lib/custom_fields.rb +++ b/vendor/plugins/custom_fields/lib/custom_fields.rb @@ -1,6 +1,5 @@ $:.unshift File.expand_path(File.dirname(__FILE__)) -require 'custom_fields/extensions/mongoid/associations/options' require 'custom_fields/extensions/mongoid/associations/embeds_many' require 'custom_fields/extensions/mongoid/document' require 'custom_fields/custom_fields_for' diff --git a/vendor/plugins/custom_fields/lib/custom_fields/custom_field.rb b/vendor/plugins/custom_fields/lib/custom_fields/custom_field.rb new file mode 100644 index 00000000..c62aac90 --- /dev/null +++ b/vendor/plugins/custom_fields/lib/custom_fields/custom_field.rb @@ -0,0 +1,63 @@ +module CustomFields + + class CustomField + include Mongoid::Document + include Mongoid::Timestamps + + ## fields ## + field :label, :type => String + field :_alias, :type => String # need it for instance in: > asset.description (description being a custom field) + field :_name, :type => String + field :kind, :type => String + field :position, :type => Integer, :default => 0 + + ## validations ## + validates_presence_of :label, :kind + + ## methods ## + + def field_type + case self.kind + when 'String', 'Text', 'Email' then String + else + self.kind.constantize + end + end + + def apply(object, association_name) + object.class.send(:set_field, self._name, { :type => self.field_type }) + object.class_eval <<-EOF + alias :#{self.safe_alias} :#{self._name} + alias :#{self.safe_alias}= :#{self._name}= + EOF + end + + def safe_alias + self.set_alias + self._alias + end + + protected + + def set_unique_name! + self._name = "custom_field_#{self.increment_counter!}" + end + + def set_alias + return if self.label.blank? && self._alias.blank? + self._alias ||= self.label.clone + self._alias.slugify!(:downcase => true, :underscore => true) + end + + def increment_counter! + next_value = (self._parent.send(:"#{self.association_name}_counter") || 0) + 1 + self._parent.send(:"#{self.association_name}_counter=", next_value) + next_value + end + + def siblings + self._parent.associations[self.association_name] + end + end + +end \ No newline at end of file diff --git a/vendor/plugins/custom_fields/lib/custom_fields/custom_fields_for.rb b/vendor/plugins/custom_fields/lib/custom_fields/custom_fields_for.rb index f1d72d85..c42bc4a1 100644 --- a/vendor/plugins/custom_fields/lib/custom_fields/custom_fields_for.rb +++ b/vendor/plugins/custom_fields/lib/custom_fields/custom_fields_for.rb @@ -27,9 +27,14 @@ module CustomFields def custom_fields_for(collection_name) puts "settings custom fields for #{collection_name}" - class_eval <<-EOV - + singular_name = collection_name.to_s.singularize + class_eval <<-EOV + field :#{singular_name}_custom_fields_counter, :type => Integer, :default => 0 + + embeds_many :#{singular_name}_custom_fields, :class_name => "::CustomFields::CustomField" + + accepts_nested_attributes_for :#{singular_name}_custom_fields, :allow_destroy => true EOV end diff --git a/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/embeds_many.rb b/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/embeds_many.rb index 73f52086..a419d36a 100644 --- a/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/embeds_many.rb +++ b/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/embeds_many.rb @@ -4,7 +4,13 @@ module Mongoid #:nodoc: class EmbedsMany < Proxy def build_with_custom_field_settings(attrs = {}, type = nil) document = build_without_custom_field_settings(attrs, type) - if self.target_custom_field_association? + + if @association_name.ends_with?('_custom_fields') + document.class_eval <<-EOV + self.associations = {} # prevent associations to be nil + embedded_in :#{@parent.class.to_s.underscore}, :inverse_of => :#{@association_name} + EOV + document.send(:set_unique_name!) document.send(:set_alias) end @@ -12,17 +18,6 @@ module Mongoid #:nodoc: end 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) - @parent.associations[target_name].options.custom_fields - end - end - end end diff --git a/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/options.rb b/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/options.rb deleted file mode 100644 index f13c81ff..00000000 --- a/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/options.rb +++ /dev/null @@ -1,10 +0,0 @@ -# encoding: utf-8 -module Mongoid #:nodoc: - module Associations #:nodoc: - class Options #:nodoc: - def custom_fields - @attributes[:custom_fields] == true - end - end - end -end \ No newline at end of file diff --git a/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/document.rb b/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/document.rb index 833fae47..e9d3e547 100644 --- a/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/document.rb +++ b/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/document.rb @@ -15,13 +15,12 @@ module Mongoid #:nodoc: alias_method_chain :parentize, :custom_fields def custom_fields_association_name(association_name) - "#{association_name.singularize}_fields".to_sym + "#{association_name.singularize}_custom_fields".to_sym end def custom_fields?(object, association_name) object.respond_to?(custom_fields_association_name(association_name)) && - object.associations[association_name] && - object.associations[association_name].options.custom_fields + object.associations[association_name] end end end