custom fields (in progress)
This commit is contained in:
parent
13cd09e3af
commit
c15c635efe
@ -24,5 +24,5 @@ class Asset
|
|||||||
self.content_type == type
|
self.content_type == type
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -5,11 +5,14 @@ class AssetCollection
|
|||||||
## fields ##
|
## fields ##
|
||||||
field :name, :type => String
|
field :name, :type => String
|
||||||
field :slug, :type => String
|
field :slug, :type => String
|
||||||
|
field :asset_fields_counter, :type => Integer, :default => 0 # FIXME (custom fields)
|
||||||
|
|
||||||
|
|
||||||
## associations ##
|
## associations ##
|
||||||
belongs_to_related :site
|
belongs_to_related :site
|
||||||
embeds_many :assets
|
embeds_many :assets, :custom_fields => true
|
||||||
# has_many_related :assets
|
|
||||||
|
embeds_many :asset_fields # FIXME (custom fields)
|
||||||
|
|
||||||
## callbacks ##
|
## callbacks ##
|
||||||
before_validate :normalize_slug
|
before_validate :normalize_slug
|
||||||
|
67
app/models/asset_field.rb
Normal file
67
app/models/asset_field.rb
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
class AssetField
|
||||||
|
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
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
## methods ##
|
||||||
|
|
||||||
|
def field_type
|
||||||
|
case self.kind
|
||||||
|
when 'String', 'Text', 'Email' then String
|
||||||
|
else
|
||||||
|
self.kind.constantize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply(object, association_name)
|
||||||
|
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}
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# def add_to_list_bottom
|
||||||
|
# self.position = (self.siblings.map(&:position).max || 0) + 1
|
||||||
|
# end
|
||||||
|
|
||||||
|
def set_unique_name!
|
||||||
|
self._name = "custom_field_#{self.increment_counter!}"
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def increment_counter!
|
||||||
|
next_value = self._parent.send(:"#{self.association_name}_counter") + 1
|
||||||
|
self._parent.send(:"#{self.association_name}_counter=", next_value)
|
||||||
|
next_value
|
||||||
|
end
|
||||||
|
|
||||||
|
def siblings
|
||||||
|
self._parent.associations[self.association_name]
|
||||||
|
end
|
||||||
|
end
|
73
config/initializers/custom_fields.rb
Normal file
73
config/initializers/custom_fields.rb
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# encoding: utf-8
|
||||||
|
module Mongoid #:nodoc:
|
||||||
|
module Associations #:nodoc:
|
||||||
|
class Options #:nodoc:
|
||||||
|
def custom_fields
|
||||||
|
@attributes[:custom_fields] == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# encoding: utf-8
|
||||||
|
module Mongoid #:nodoc:
|
||||||
|
module Associations #: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?
|
||||||
|
document.send(:set_unique_name!)
|
||||||
|
document.send(:set_alias)
|
||||||
|
end
|
||||||
|
document
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method_chain :build, :custom_field_settings
|
||||||
|
|
||||||
|
def target_custom_field_association?
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
# encoding: utf-8
|
||||||
|
module Mongoid #:nodoc:
|
||||||
|
module Document
|
||||||
|
module InstanceMethods
|
||||||
|
def parentize_with_custom_fields(object, association_name)
|
||||||
|
# puts "...parentize_with_custom_fields...#{self.inspect} - #{object.inspect} - #{association_name}"
|
||||||
|
parentize_without_custom_fields(object, association_name)
|
||||||
|
|
||||||
|
if self.custom_fields?(object, association_name)
|
||||||
|
# puts "custom fields = #{object.asset_fields.inspect}"
|
||||||
|
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 "))))))))"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method_chain :parentize, :custom_fields
|
||||||
|
|
||||||
|
def custom_fields_association_name(association_name)
|
||||||
|
"#{association_name.singularize}_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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
doc/TODO
7
doc/TODO
@ -49,6 +49,13 @@ x domain scoping when authenticating
|
|||||||
- custom resizing
|
- custom resizing
|
||||||
- assets uploader:
|
- assets uploader:
|
||||||
- remove old files if new one
|
- remove old files if new one
|
||||||
|
- custom fields:
|
||||||
|
- renaming fields
|
||||||
|
- ui
|
||||||
|
- rename asset_field
|
||||||
|
- apply in asset_field
|
||||||
|
- extract a plugin from custom fields
|
||||||
|
- field position
|
||||||
|
|
||||||
BACKLOG:
|
BACKLOG:
|
||||||
- liquid rendering engine
|
- liquid rendering engine
|
||||||
|
@ -61,4 +61,10 @@ end
|
|||||||
## Theme assets ##
|
## Theme assets ##
|
||||||
Factory.define :theme_asset do |a|
|
Factory.define :theme_asset do |a|
|
||||||
a.association :site
|
a.association :site
|
||||||
end
|
end
|
||||||
|
|
||||||
|
## Asset collection ##
|
||||||
|
Factory.define :asset_collection do |s|
|
||||||
|
s.association :site, :factory => :site
|
||||||
|
s.name 'Trip to Chicago'
|
||||||
|
end
|
||||||
|
106
spec/models/asset_collections_spec.rb
Normal file
106
spec/models/asset_collections_spec.rb
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe AssetCollection do
|
||||||
|
|
||||||
|
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.asset_fields.build :label => 'My Description', :_alias => 'description', :kind => 'Text'
|
||||||
|
@collection.asset_fields.build :label => 'Active', :kind => 'Boolean'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'define 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 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 '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
|
||||||
|
|
||||||
|
# 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'
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_asset(collection)
|
||||||
|
collection.assets.build(:name => 'Asset on steroids', :description => 'Lorem ipsum', :active => true)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user