adding contents works + add spec + enhance content types
This commit is contained in:
parent
61958d9452
commit
4534a11ce4
@ -34,7 +34,7 @@ module Admin
|
|||||||
render :action => "edit"
|
render :action => "edit"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@content_type = current_site.content_types.find(params[:id])
|
@content_type = current_site.content_types.find(params[:id])
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ module Admin
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@content = @content_type.contents.build(params[:content])
|
@content = @content_type.contents.build(params[:content_instance])
|
||||||
|
|
||||||
if @content.save
|
if @content.save
|
||||||
flash_success!
|
flash_success!
|
||||||
@ -32,7 +32,7 @@ module Admin
|
|||||||
def update
|
def update
|
||||||
@content = @content_type.contents.find(params[:id])
|
@content = @content_type.contents.find(params[:id])
|
||||||
|
|
||||||
if @content.update_attributes(params[:content])
|
if @content.update_attributes(params[:content_instance])
|
||||||
flash_success!
|
flash_success!
|
||||||
redirect_to edit_admin_content_url(@content_type.slug, @content)
|
redirect_to edit_admin_content_url(@content_type.slug, @content)
|
||||||
else
|
else
|
||||||
@ -40,6 +40,10 @@ module Admin
|
|||||||
render :action => "edit"
|
render :action => "edit"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sort
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@content = @content_type.contents.find(params[:id])
|
@content = @content_type.contents.find(params[:id])
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
module Admin::CustomFieldsHelper
|
module Admin::CustomFieldsHelper
|
||||||
|
|
||||||
# def options_for_field_kind(selected = nil)
|
|
||||||
# # %w{String Text Boolean Email File Date}
|
|
||||||
# options = %w{String Text}.map do |kind|
|
|
||||||
# [t("admin.custom_fields.kind.#{kind.downcase}"), kind]
|
|
||||||
# end
|
|
||||||
# options_for_select(options, selected)
|
|
||||||
# end
|
|
||||||
|
|
||||||
def options_for_field_kind(selected = nil)
|
def options_for_field_kind(selected = nil)
|
||||||
# %w{String Text Boolean Email File Date}
|
# %w{String Text Boolean Email File Date}
|
||||||
options = %w{String Text}.map do |kind|
|
options = %w{String Text}.map do |kind|
|
||||||
@ -15,4 +7,18 @@ module Admin::CustomFieldsHelper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def options_for_order_by(content_type, collection_name)
|
||||||
|
options = %w{updated_at position}.map do |type|
|
||||||
|
[t("admin.content_types.form.order_by.#{type.gsub(/^_/, '')}"), type]
|
||||||
|
end
|
||||||
|
options + options_for_highlighted_field(content_type, collection_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def options_for_highlighted_field(content_type, collection_name)
|
||||||
|
custom_fields_collection_name = "ordered_#{collection_name.singularize}_custom_fields".to_sym
|
||||||
|
collection = content_type.send(custom_fields_collection_name)
|
||||||
|
collection.delete_if { |f| f.label == 'field name' }
|
||||||
|
collection.map { |field| [field.label, field._name] }
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -2,7 +2,24 @@ class ContentInstance
|
|||||||
include Mongoid::Document
|
include Mongoid::Document
|
||||||
include Mongoid::Timestamps
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
# fields ##
|
## fields (dynamic fields) ##
|
||||||
field :name
|
field :position, :type => Integer, :default => 0
|
||||||
|
|
||||||
|
## validations ##
|
||||||
|
validate :require_highlighted_field
|
||||||
|
|
||||||
|
## associations ##
|
||||||
|
embedded_in :content_type, :inverse_of => :contents
|
||||||
|
|
||||||
|
## methods ##
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def require_highlighted_field
|
||||||
|
_alias = self.content_type.highlighted_field._alias.to_sym
|
||||||
|
if self.send(_alias).blank?
|
||||||
|
self.errors.add(_alias, :blank)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -1,13 +1,14 @@
|
|||||||
class ContentType
|
class ContentType
|
||||||
include Mongoid::Document
|
include Mongoid::Document
|
||||||
include Mongoid::Timestamps
|
include Mongoid::Timestamps
|
||||||
# include Mongoid::CustomFields
|
include Mongoid::CustomFields
|
||||||
|
|
||||||
## fields ##
|
## fields ##
|
||||||
field :name
|
field :name
|
||||||
field :description
|
field :description
|
||||||
field :slug
|
field :slug
|
||||||
field :order_by
|
field :order_by
|
||||||
|
field :highlighted_field_name
|
||||||
|
|
||||||
## associations ##
|
## associations ##
|
||||||
belongs_to_related :site
|
belongs_to_related :site
|
||||||
@ -21,10 +22,26 @@ class ContentType
|
|||||||
validates_uniqueness_of :slug, :scope => :site
|
validates_uniqueness_of :slug, :scope => :site
|
||||||
|
|
||||||
## behaviours ##
|
## behaviours ##
|
||||||
# custom_fields_for :contents
|
custom_fields_for :contents
|
||||||
|
|
||||||
## methods ##
|
## methods ##
|
||||||
|
|
||||||
|
def ordered_contents
|
||||||
|
self.contents.sort { |a, b| (a.position || 0) <=> (b.position || 0) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def contents_order
|
||||||
|
self.ordered_contents.collect(&:id).join(',')
|
||||||
|
end
|
||||||
|
|
||||||
|
def contents_order=(order)
|
||||||
|
@contents_order = order
|
||||||
|
end
|
||||||
|
|
||||||
|
def highlighted_field
|
||||||
|
self.content_custom_fields.detect { |f| f._name == self.highlighted_field_name }
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def normalize_slug
|
def normalize_slug
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
- title link_to(@collection.name.blank? ? @collection.name_was : @collection.name, '#', :rel => 'asset_collection_name', :title => t('.ask_for_name'), :class => 'editable')
|
- title link_to(@collection.name.blank? ? @collection.name_was : @collection.name, '#', :rel => 'asset_collection_name', :title => t('.ask_for_name'), :class => 'editable')
|
||||||
|
|
||||||
- content_for :head do
|
- content_for :head do
|
||||||
= javascript_include_tag 'admin/asset_collections.js', 'admin/custom_fields'
|
= javascript_include_tag 'admin/asset_collections', 'admin/custom_fields'
|
||||||
|
|
||||||
- content_for :submenu do
|
- content_for :submenu do
|
||||||
= render 'admin/shared/menu/assets'
|
= render 'admin/shared/menu/assets'
|
||||||
@ -25,6 +25,6 @@
|
|||||||
= f.input :name
|
= f.input :name
|
||||||
= f.input :slug, :required => false
|
= f.input :slug, :required => false
|
||||||
|
|
||||||
= render 'custom_fields', :f => f
|
= render 'admin/shared/custom_fields', :f => f, :collection_name => 'assets'
|
||||||
|
|
||||||
= render 'admin/shared/form_actions', :delete_button => link_to(content_tag(:span, t('.destroy')), admin_asset_collection_url(@collection), :confirm => t('admin.messages.confirm'), :method => :delete, :class => 'button small remove'), :button_label => :update
|
= render 'admin/shared/form_actions', :delete_button => link_to(content_tag(:span, t('.destroy')), admin_asset_collection_url(@collection), :confirm => t('admin.messages.confirm'), :method => :delete, :class => 'button small remove'), :button_label => :update
|
@ -1,4 +1,13 @@
|
|||||||
|
- content_for :head do
|
||||||
|
= javascript_include_tag 'admin/custom_fields'
|
||||||
|
|
||||||
= f.inputs :name => :information do
|
= f.inputs :name => :information do
|
||||||
= f.input :name
|
= f.input :name
|
||||||
= f.input :slug, :required => false
|
= f.input :slug
|
||||||
= f.input :description, :as => 'text'
|
= f.input :description
|
||||||
|
|
||||||
|
= render 'admin/shared/custom_fields', :f => f, :collection_name => 'contents'
|
||||||
|
|
||||||
|
= f.foldable_inputs :name => :options, :class => 'switchable' do
|
||||||
|
= f.input :highlighted_field_name, :as => :select, :collection => options_for_highlighted_field(f.object, 'contents'), :include_blank => false
|
||||||
|
= f.input :order_by, :as => :select, :collection => options_for_order_by(f.object, 'contents'), :include_blank => false
|
10
app/views/admin/contents/_form.html.haml
Normal file
10
app/views/admin/contents/_form.html.haml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
- highlighted_field_name = @content.content_type.highlighted_field_name
|
||||||
|
|
||||||
|
= f.inputs :name => :other_fields do
|
||||||
|
- @content.custom_fields.each do |field|
|
||||||
|
- required = highlighted_field_name == field._name
|
||||||
|
|
||||||
|
- if field.string?
|
||||||
|
= f.input field._alias.to_sym, :label => field.label, :required => required
|
||||||
|
- elsif field.text?
|
||||||
|
= f.input field._alias.to_sym, :label => field.label, :as => :text, :required => required
|
15
app/views/admin/contents/edit.html.haml
Normal file
15
app/views/admin/contents/edit.html.haml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
- title t('.title', :type => @content_type.name.capitalize)
|
||||||
|
|
||||||
|
- content_for :submenu do
|
||||||
|
= render 'admin/shared/menu/contents'
|
||||||
|
|
||||||
|
- content_for :buttons do
|
||||||
|
= admin_button_tag t('admin.contents.index.edit'), edit_admin_content_type_url(@content_type), :class => 'edit'
|
||||||
|
|
||||||
|
%p= @content_type.description
|
||||||
|
|
||||||
|
= semantic_form_for @content, :url => admin_content_url(@content_type.slug, @content), :html => { :multipart => true } do |form|
|
||||||
|
|
||||||
|
= render 'form', :f => form
|
||||||
|
|
||||||
|
= render 'admin/shared/form_actions', :back_url => admin_contents_url(@content_type.slug), :button_label => :update
|
@ -1,8 +1,11 @@
|
|||||||
- title t('.title', :type => @content_type.name)
|
- title t('.title', :type => @content_type.name.capitalize)
|
||||||
|
|
||||||
- content_for :submenu do
|
- content_for :submenu do
|
||||||
= render 'admin/shared/menu/contents'
|
= render 'admin/shared/menu/contents'
|
||||||
|
|
||||||
|
- content_for :head do
|
||||||
|
= javascript_include_tag 'admin/contents'
|
||||||
|
|
||||||
- content_for :buttons do
|
- content_for :buttons do
|
||||||
= admin_button_tag :edit, edit_admin_content_type_url(@content_type), :class => 'edit'
|
= admin_button_tag :edit, edit_admin_content_type_url(@content_type), :class => 'edit'
|
||||||
= admin_button_tag :download, '#', :class => 'download'
|
= admin_button_tag :download, '#', :class => 'download'
|
||||||
@ -14,4 +17,21 @@
|
|||||||
- if @contents.empty?
|
- if @contents.empty?
|
||||||
%p.no-items= t('.no_items', :url => new_admin_content_url(@content_type.slug))
|
%p.no-items= t('.no_items', :url => new_admin_content_url(@content_type.slug))
|
||||||
- else
|
- else
|
||||||
foo bar
|
%ul{ :id => 'contents-list', :class => "list #{'sortable' if @content_type.order_by == 'position'}" }
|
||||||
|
- @contents.each do |content|
|
||||||
|
%li.content{ :id => "content-#{content._id}" }
|
||||||
|
- if @content_type.order_by == 'position'
|
||||||
|
%em
|
||||||
|
%strong
|
||||||
|
= link_to content.send(@content_type.highlighted_field_name), edit_admin_content_path(@content_type.slug, content)
|
||||||
|
.more
|
||||||
|
%span
|
||||||
|
= t('admin.contents.index.updated_at')
|
||||||
|
= l content.updated_at, :format => :short rescue 'n/a'
|
||||||
|
|
||||||
|
= link_to image_tag('admin/list/icons/trash.png'), admin_content_path(@content_type.slug, content), :class => 'remove', :confirm => t('admin.messages.confirm'), :method => :delete
|
||||||
|
|
||||||
|
= form_tag sort_admin_contents_path(@content_type.slug), :method => :put, :class => 'formtastic' do
|
||||||
|
= hidden_field_tag :order
|
||||||
|
|
||||||
|
= render 'admin/shared/form_actions', :delete_button => link_to(content_tag(:span, t('.destroy')), admin_content_type_url(@content_type), :confirm => t('admin.messages.confirm'), :method => :delete, :class => 'button small remove'), :button_label => :update
|
15
app/views/admin/contents/new.html.haml
Normal file
15
app/views/admin/contents/new.html.haml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
- title t('.title', :type => @content_type.name.capitalize)
|
||||||
|
|
||||||
|
- content_for :submenu do
|
||||||
|
= render 'admin/shared/menu/contents'
|
||||||
|
|
||||||
|
- content_for :buttons do
|
||||||
|
= admin_button_tag t('admin.contents.index.edit'), edit_admin_content_type_url(@content_type), :class => 'edit'
|
||||||
|
|
||||||
|
%p= @content_type.description
|
||||||
|
|
||||||
|
= semantic_form_for @content, :url => admin_contents_url(@content_type.slug), :html => { :multipart => true } do |form|
|
||||||
|
|
||||||
|
= render 'form', :f => form
|
||||||
|
|
||||||
|
= render 'admin/shared/form_actions', :back_url => admin_contents_url(@content_type.slug), :button_label => :create
|
@ -1,6 +1,10 @@
|
|||||||
|
- collection_name = "#{collection_name.singularize}_custom_fields"
|
||||||
|
- custom_fields = f.object.send(collection_name.to_sym)
|
||||||
|
- ordered_custom_fields = f.object.send(:"ordered_#{collection_name}")
|
||||||
|
|
||||||
= f.foldable_inputs :name => :custom_fields, :class => 'editable-list fields' do
|
= f.foldable_inputs :name => :custom_fields, :class => 'editable-list fields' do
|
||||||
- f.object.ordered_asset_custom_fields.each do |field|
|
- ordered_custom_fields.each do |field|
|
||||||
= f.fields_for :asset_custom_fields, field, :child_index => field._index do |g|
|
= f.fields_for collection_name.to_sym, field, :child_index => field._index do |g|
|
||||||
%li{ :class => "item added #{'error' unless field.errors.empty?}"}
|
%li{ :class => "item added #{'error' unless field.errors.empty?}"}
|
||||||
%span.handle
|
%span.handle
|
||||||
= image_tag 'admin/form/icons/drag.png'
|
= image_tag 'admin/form/icons/drag.png'
|
||||||
@ -20,7 +24,7 @@
|
|||||||
%span.actions
|
%span.actions
|
||||||
= link_to image_tag('admin/form/icons/trash.png'), '#', :class => 'remove first', :confirm => t('admin.messages.confirm')
|
= link_to image_tag('admin/form/icons/trash.png'), '#', :class => 'remove first', :confirm => t('admin.messages.confirm')
|
||||||
|
|
||||||
= f.fields_for :asset_custom_fields, @collection.asset_custom_fields.build(:label => 'field name'), :child_index => '-1' do |g|
|
= f.fields_for collection_name.to_sym, custom_fields.build(:label => 'field name'), :child_index => '-1' do |g|
|
||||||
%li{ :class => 'item template' }
|
%li{ :class => 'item template' }
|
||||||
%span.handle
|
%span.handle
|
||||||
= image_tag 'admin/form/icons/drag.png'
|
= image_tag 'admin/form/icons/drag.png'
|
@ -150,6 +150,10 @@ en:
|
|||||||
help: "Your model should have one field at least. The items created from this content type would have their first field mandatory."
|
help: "Your model should have one field at least. The items created from this content type would have their first field mandatory."
|
||||||
show_items: show items
|
show_items: show items
|
||||||
new_item: new item
|
new_item: new item
|
||||||
|
form:
|
||||||
|
order_by:
|
||||||
|
updated_at: 'By "updated at" date'
|
||||||
|
position: Manually
|
||||||
|
|
||||||
contents:
|
contents:
|
||||||
index:
|
index:
|
||||||
@ -158,6 +162,11 @@ en:
|
|||||||
download: download items
|
download: download items
|
||||||
new: new item
|
new: new item
|
||||||
no_items: "There are no items for now. Just click <a href=\"{{url}}\">here</a> to create the first one."
|
no_items: "There are no items for now. Just click <a href=\"{{url}}\">here</a> to create the first one."
|
||||||
|
new:
|
||||||
|
title: '{{type}} — new item'
|
||||||
|
edit:
|
||||||
|
title: '{{type}} — editing item'
|
||||||
|
|
||||||
|
|
||||||
formtastic:
|
formtastic:
|
||||||
titles:
|
titles:
|
||||||
|
@ -45,8 +45,9 @@ Locomotive::Application.routes.draw do |map|
|
|||||||
|
|
||||||
resources :content_types
|
resources :content_types
|
||||||
|
|
||||||
resources :contents, :path => "content_types/:slug/contents"
|
resources :contents, :path => "content_types/:slug/contents" do
|
||||||
|
put :sort, :on => :collection
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# magic urls
|
# magic urls
|
||||||
|
3
doc/TODO
3
doc/TODO
@ -1,6 +1,9 @@
|
|||||||
BOARD:
|
BOARD:
|
||||||
- content types / models (CRUD)
|
- content types / models (CRUD)
|
||||||
|
- require a custom field at least
|
||||||
|
- pre-select the first custom field as the highlighted one
|
||||||
- contents (CRUD)
|
- contents (CRUD)
|
||||||
|
- sort contents
|
||||||
|
|
||||||
BACKLOG:
|
BACKLOG:
|
||||||
- liquid rendering engine
|
- liquid rendering engine
|
||||||
|
16
public/javascripts/admin/contents.js
Normal file
16
public/javascripts/admin/contents.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
var updateContentsOrder = function() {
|
||||||
|
var list = $('ul#contents-list.sortable');
|
||||||
|
var ids = jQuery.map(list.sortable('toArray'), function(e) {
|
||||||
|
return e.match(/content-(\w+)/)[1];
|
||||||
|
}).join(',');
|
||||||
|
$('#order').val(ids || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('ul#contents-list.sortable').sortable({
|
||||||
|
items: 'li.content',
|
||||||
|
stop: function(event, ui) { updateContentsOrder(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -54,6 +54,14 @@ ul.list li {
|
|||||||
background: transparent url(/images/admin/list/item.png) no-repeat 0 0;
|
background: transparent url(/images/admin/list/item.png) no-repeat 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.list li em {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
background: transparent url(/images/admin/list/item-left.png) no-repeat left 0;
|
||||||
|
height: 31px;
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
ul.list li strong a {
|
ul.list li strong a {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 2px;
|
top: 2px;
|
||||||
@ -151,6 +159,22 @@ div#asset-uploader { display: inline-block; margin-left: 10px; }
|
|||||||
div#asset-uploader span.spinner { position: relative; top: -3px; display: none; }
|
div#asset-uploader span.spinner { position: relative; top: -3px; display: none; }
|
||||||
div#uploadAssetsInputQueue { display: none; }
|
div#uploadAssetsInputQueue { display: none; }
|
||||||
|
|
||||||
|
/* ___ contents ___ */
|
||||||
|
|
||||||
|
#contents-list li { background: none; }
|
||||||
|
|
||||||
|
#contents-list li em {
|
||||||
|
background-position: left -31px;
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
#contents-list li strong {
|
||||||
|
margin-left: 18px;
|
||||||
|
display: block;
|
||||||
|
height: 31px;
|
||||||
|
background: transparent url(/images/admin/list/item-right.png) no-repeat right 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ___ pages ___ */
|
/* ___ pages ___ */
|
||||||
|
|
||||||
|
33
spec/models/content_instance_spec.rb
Normal file
33
spec/models/content_instance_spec.rb
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe ContentInstance do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
Site.any_instance.stubs(:create_default_pages!).returns(true)
|
||||||
|
@content_type = Factory.build(:content_type)
|
||||||
|
@content_type.content_custom_fields.build :label => 'Title', :kind => 'String'
|
||||||
|
@content_type.content_custom_fields.build :label => 'Description', :kind => 'Text'
|
||||||
|
@content_type.highlighted_field_name = 'custom_field_1'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when validating' do
|
||||||
|
|
||||||
|
it 'should be valid' do
|
||||||
|
build_content.should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
# Validations ##
|
||||||
|
|
||||||
|
it 'should validate presence of title' do
|
||||||
|
content = build_content :title => nil
|
||||||
|
content.should_not be_valid
|
||||||
|
content.errors[:title].should == ["can't be blank"]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_content(options = {})
|
||||||
|
@content_type.contents.build({ :title => 'Locomotive', :description => 'Lorem ipsum....' }.merge(options))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -6,30 +6,34 @@ describe ContentType do
|
|||||||
Site.any_instance.stubs(:create_default_pages!).returns(true)
|
Site.any_instance.stubs(:create_default_pages!).returns(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should have a valid factory' do
|
context 'when validating' do
|
||||||
Factory.build(:content_type).should be_valid
|
|
||||||
end
|
it 'should have a valid factory' do
|
||||||
|
Factory.build(:content_type).should be_valid
|
||||||
# Validations ##
|
|
||||||
|
|
||||||
%w{site name}.each do |field|
|
|
||||||
it "should validate presence of #{field}" do
|
|
||||||
content_type = Factory.build(:content_type, field.to_sym => nil)
|
|
||||||
content_type.should_not be_valid
|
|
||||||
content_type.errors[field.to_sym].should == ["can't be blank"]
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
it 'should validate presence of slug' do
|
# Validations ##
|
||||||
content_type = Factory.build(:content_type, :name => nil, :slug => nil)
|
|
||||||
content_type.should_not be_valid
|
|
||||||
content_type.errors[:slug].should == ["can't be blank"]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should validate uniqueness of slug' do
|
%w{site name}.each do |field|
|
||||||
content_type = Factory(:content_type)
|
it "should validate presence of #{field}" do
|
||||||
(content_type = Factory.build(:content_type, :site => content_type.site)).should_not be_valid
|
content_type = Factory.build(:content_type, field.to_sym => nil)
|
||||||
content_type.errors[:slug].should == ["is already taken"]
|
content_type.should_not be_valid
|
||||||
|
content_type.errors[field.to_sym].should == ["can't be blank"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should validate presence of slug' do
|
||||||
|
content_type = Factory.build(:content_type, :name => nil, :slug => nil)
|
||||||
|
content_type.should_not be_valid
|
||||||
|
content_type.errors[:slug].should == ["can't be blank"]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should validate uniqueness of slug' do
|
||||||
|
content_type = Factory(:content_type)
|
||||||
|
(content_type = Factory.build(:content_type, :site => content_type.site)).should_not be_valid
|
||||||
|
content_type.errors[:slug].should == ["is already taken"]
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -6,6 +6,7 @@ module Mongoid #:nodoc:
|
|||||||
parentize_without_custom_fields(object, association_name)
|
parentize_without_custom_fields(object, association_name)
|
||||||
|
|
||||||
if self.custom_fields?(object, association_name)
|
if self.custom_fields?(object, association_name)
|
||||||
|
puts "[parentize_with_custom_fields] association_name = #{association_name} / #{self.custom_fields_association_name(association_name)}"
|
||||||
self.class.send(:define_method, :custom_fields) do
|
self.class.send(:define_method, :custom_fields) do
|
||||||
fields = object.send(self.custom_fields_association_name(association_name))
|
fields = object.send(self.custom_fields_association_name(association_name))
|
||||||
fields.sort { |a, b| (a.position || 0) <=> (b.position || 0) }
|
fields.sort { |a, b| (a.position || 0) <=> (b.position || 0) }
|
||||||
|
Loading…
Reference in New Issue
Block a user