custom field validation is more robust + editing new fields for assets works now
This commit is contained in:
parent
10ffc2e8bb
commit
1ed613ede8
@ -35,11 +35,7 @@ class AssetCollection
|
||||
def assets_order=(order)
|
||||
@assets_order = order
|
||||
end
|
||||
|
||||
def ordered_asset_custom_fields # FIXME (custom fields)
|
||||
self.asset_custom_fields.sort { |a, b| (a.position || 0) <=> (b.position || 0) }
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
def normalize_slug
|
||||
|
@ -1,4 +1,4 @@
|
||||
= f.foldable_inputs :name => :custom_fields, :class => 'editable-list fields off' do
|
||||
= f.foldable_inputs :name => :custom_fields, :class => 'editable-list fields' do
|
||||
- f.object.ordered_asset_custom_fields.each do |field|
|
||||
= f.fields_for :asset_custom_fields, field, :child_index => field._index do |g|
|
||||
%li{ :class => "item added #{'error' unless field.errors.empty?}"}
|
||||
|
@ -2,6 +2,14 @@
|
||||
= f.input :name
|
||||
= f.input :source
|
||||
|
||||
- unless @asset.custom_fields.empty?
|
||||
= f.inputs :name => :other_fields do
|
||||
- @asset.custom_fields.each do |field|
|
||||
- if field.string?
|
||||
= f.input field._alias.to_sym, :label => field.label
|
||||
- elsif field.text?
|
||||
= f.input field._alias.to_sym, :label => field.label, :as => :text
|
||||
|
||||
- if @asset.image?
|
||||
= f.foldable_inputs :name => "#{t('formtastic.titles.preview')} #{image_dimensions_and_size(@asset)}", :class => 'preview' do
|
||||
%li
|
||||
|
@ -155,6 +155,7 @@ en:
|
||||
preview: Preview
|
||||
options: Advanced options
|
||||
custom_fields: Custom fields
|
||||
other_fields: Other information
|
||||
labels:
|
||||
theme_asset:
|
||||
new:
|
||||
|
10
doc/TODO
10
doc/TODO
@ -55,16 +55,16 @@ x domain scoping when authenticating
|
||||
x ui
|
||||
x field position
|
||||
x rename asset_field
|
||||
- apply in asset_field
|
||||
- nested attributes
|
||||
- keep tracks of all custom fields (adding / editing assets)
|
||||
- custom fields -> metadata keys
|
||||
- duplicate fields
|
||||
x nested attributes
|
||||
x keep tracks of all custom fields (adding / editing assets) + order them
|
||||
x duplicate fields
|
||||
- apply in asset_field (in order to handle Date, File, ...etc)
|
||||
|
||||
BACKLOG:
|
||||
- liquid rendering engine
|
||||
- theme assets
|
||||
- assets collection
|
||||
- custom models
|
||||
|
||||
- devise messages in French
|
||||
- localize devise emails
|
||||
|
@ -9,10 +9,52 @@ describe AssetCollection do
|
||||
describe 'custom fields (beta)' do
|
||||
|
||||
before(:each) do
|
||||
@collection = Factory.build(:asset_collection, :site => nil)
|
||||
site = Factory.build(:site)
|
||||
Site.stubs(:find).returns(site)
|
||||
@collection = Factory.build(:asset_collection, :site => site)
|
||||
@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 'unit' do
|
||||
|
||||
before(:each) do
|
||||
@field = CustomFields::CustomField.new(:kind => 'String')
|
||||
end
|
||||
|
||||
it 'should tell if it is a String' do
|
||||
@field.string?.should be_true
|
||||
end
|
||||
|
||||
it 'should tell if it is a Text' do
|
||||
@field.kind = 'Text'
|
||||
@field.text?.should be_true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'validation' do
|
||||
|
||||
%w{label kind}.each do |key|
|
||||
it "should validate presence of #{key}" do
|
||||
field = @collection.asset_custom_fields.build({ :label => 'Shortcut', :kind => 'String' }.merge(key.to_sym => nil))
|
||||
field.should_not be_valid
|
||||
field.errors[key.to_sym].should == ["can't be blank"]
|
||||
end
|
||||
end
|
||||
|
||||
it 'should not have unique label' do
|
||||
field = @collection.asset_custom_fields.build :label => 'Active', :kind => 'Boolean'
|
||||
field.should_not be_valid
|
||||
field.errors[:label].should == ["is already taken"]
|
||||
end
|
||||
|
||||
it 'should invalidate parent if custom field is not valid' do
|
||||
field = @collection.asset_custom_fields.build
|
||||
@collection.should_not be_valid
|
||||
@collection.asset_custom_fields.last.errors[:label].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'define core attributes' do
|
||||
@ -36,6 +78,7 @@ describe AssetCollection do
|
||||
lambda {
|
||||
asset.description
|
||||
asset.active
|
||||
asset.custom_fields.size.should == 2
|
||||
}.should_not raise_error
|
||||
end
|
||||
|
||||
@ -97,11 +140,11 @@ describe AssetCollection do
|
||||
|
||||
context 'managing from hash' do
|
||||
|
||||
before(:each) do
|
||||
site = Factory.build(:site)
|
||||
Site.stubs(:find).returns(site)
|
||||
@collection.site = site
|
||||
end
|
||||
# before(:each) do
|
||||
# site = Factory.build(:site)
|
||||
# Site.stubs(:find).returns(site)
|
||||
# @collection.site = site
|
||||
# end
|
||||
|
||||
it 'should add new field' do
|
||||
@collection.asset_custom_fields.clear
|
||||
|
@ -13,8 +13,15 @@ module CustomFields
|
||||
|
||||
## validations ##
|
||||
validates_presence_of :label, :kind
|
||||
validate :uniqueness_of_label
|
||||
|
||||
## methods ##
|
||||
|
||||
%w{String Text Email Boolean Date File}.each do |kind|
|
||||
define_method "#{kind.downcase}?" do
|
||||
self.kind == kind
|
||||
end
|
||||
end
|
||||
|
||||
def field_type
|
||||
case self.kind
|
||||
@ -25,7 +32,10 @@ module CustomFields
|
||||
end
|
||||
|
||||
def apply(object, association_name)
|
||||
return unless self.valid?
|
||||
|
||||
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}=
|
||||
@ -38,6 +48,13 @@ module CustomFields
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def uniqueness_of_label
|
||||
duplicate = self.siblings.detect { |f| f.label == self.label && f._id != self._id }
|
||||
if not duplicate.nil?
|
||||
self.errors.add(:label, :taken)
|
||||
end
|
||||
end
|
||||
|
||||
def set_unique_name!
|
||||
self._name ||= "custom_field_#{self.increment_counter!}"
|
||||
@ -56,7 +73,7 @@ module CustomFields
|
||||
end
|
||||
|
||||
def siblings
|
||||
self._parent.associations[self.association_name]
|
||||
self._parent.send(self.association_name)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -8,19 +8,19 @@ module CustomFields
|
||||
|
||||
# Enhance an embedded collection by providing methods to manage custom fields
|
||||
#
|
||||
# class Person
|
||||
# embeds_many :addresses
|
||||
# custom_fields_for :addresses
|
||||
# class Company
|
||||
# embeds_many :employees
|
||||
# custom_fields_for :employees
|
||||
# end
|
||||
#
|
||||
# class Address
|
||||
# embedded_in :person, :inverse_of => :addresses
|
||||
# field :street, String
|
||||
# class Employee
|
||||
# embedded_in :company, :inverse_of => :employees
|
||||
# field :name, String
|
||||
# end
|
||||
#
|
||||
# person.address_fields.build :label => 'Floor', :kind => 'String'
|
||||
# company.employee_custom_fields.build :label => 'His/her position', :_alias => 'position', :kind => 'String'
|
||||
#
|
||||
# person.addresses.build :street => 'Laflin Street', :floor => '42'
|
||||
# company.employees.build :name => 'Mickael Scott', :position => 'Regional manager'
|
||||
#
|
||||
module ClassMethods
|
||||
|
||||
@ -34,7 +34,13 @@ module CustomFields
|
||||
|
||||
embeds_many :#{singular_name}_custom_fields, :class_name => "::CustomFields::CustomField"
|
||||
|
||||
validates_associated :#{singular_name}_custom_fields
|
||||
|
||||
accepts_nested_attributes_for :#{singular_name}_custom_fields, :allow_destroy => true
|
||||
|
||||
def ordered_#{singular_name}_custom_fields
|
||||
self.#{singular_name}_custom_fields.sort { |a, b| (a.position || 0) <=> (b.position || 0) }
|
||||
end
|
||||
EOV
|
||||
end
|
||||
|
||||
|
@ -6,6 +6,11 @@ module Mongoid #:nodoc:
|
||||
parentize_without_custom_fields(object, association_name)
|
||||
|
||||
if self.custom_fields?(object, association_name)
|
||||
self.class.send(:define_method, :custom_fields) do
|
||||
fields = object.send(self.custom_fields_association_name(association_name))
|
||||
fields.sort { |a, b| (a.position || 0) <=> (b.position || 0) }
|
||||
end
|
||||
|
||||
object.send(self.custom_fields_association_name(association_name)).each do |field|
|
||||
field.apply(self, association_name)
|
||||
end
|
||||
@ -20,7 +25,7 @@ module Mongoid #:nodoc:
|
||||
|
||||
def custom_fields?(object, association_name)
|
||||
object.respond_to?(custom_fields_association_name(association_name)) &&
|
||||
object.associations[association_name]
|
||||
object.associations[association_name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user