refactoring of CustomField plugin in progress (cleaned a lot)

This commit is contained in:
dinedine 2010-05-21 02:34:32 +02:00
parent 9d134599b2
commit 7171f603f8
9 changed files with 105 additions and 54 deletions

View File

@ -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

View File

@ -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 ##

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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