fix issue #333
This commit is contained in:
parent
11d92ab80e
commit
3f6e7acda6
20
Gemfile.lock
20
Gemfile.lock
@ -17,13 +17,13 @@ GIT
|
|||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/locomotivecms/custom_fields.git
|
remote: git://github.com/locomotivecms/custom_fields.git
|
||||||
revision: e54c3ddfce0e24668d02c372c6143a722718e215
|
revision: 5b0e68859eaca41ac9d7a0231c6cd68ad66018b8
|
||||||
branch: 2.0.0.rc
|
branch: 2.0.0.rc
|
||||||
specs:
|
specs:
|
||||||
custom_fields (2.0.0.rc8)
|
custom_fields (2.0.0.rc9)
|
||||||
activesupport (~> 3.2.1)
|
activesupport (~> 3.2.1)
|
||||||
carrierwave-mongoid (~> 0.1.3)
|
carrierwave-mongoid (~> 0.1.3)
|
||||||
mongoid (~> 2.4.5)
|
mongoid (~> 2.4.7)
|
||||||
|
|
||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
@ -36,7 +36,7 @@ PATH
|
|||||||
carrierwave-mongoid (~> 0.1.3)
|
carrierwave-mongoid (~> 0.1.3)
|
||||||
cells (~> 3.8.0)
|
cells (~> 3.8.0)
|
||||||
codemirror-rails (~> 2.21)
|
codemirror-rails (~> 2.21)
|
||||||
custom_fields (~> 2.0.0.rc8)
|
custom_fields (~> 2.0.0.rc9)
|
||||||
devise (~> 1.5.3)
|
devise (~> 1.5.3)
|
||||||
dragonfly (~> 0.9.8)
|
dragonfly (~> 0.9.8)
|
||||||
flash_cookie_session (~> 1.1.1)
|
flash_cookie_session (~> 1.1.1)
|
||||||
@ -112,8 +112,8 @@ GEM
|
|||||||
xpath (~> 0.1.4)
|
xpath (~> 0.1.4)
|
||||||
carrierwave (0.5.8)
|
carrierwave (0.5.8)
|
||||||
activesupport (~> 3.0)
|
activesupport (~> 3.0)
|
||||||
carrierwave-mongoid (0.1.3)
|
carrierwave-mongoid (0.1.4)
|
||||||
carrierwave (>= 0.5.6)
|
carrierwave (~> 0.5.6)
|
||||||
mongoid (~> 2.1)
|
mongoid (~> 2.1)
|
||||||
cells (3.8.3)
|
cells (3.8.3)
|
||||||
actionpack (~> 3.0)
|
actionpack (~> 3.0)
|
||||||
@ -175,7 +175,7 @@ GEM
|
|||||||
formtastic (2.0.2)
|
formtastic (2.0.2)
|
||||||
rails (~> 3.0)
|
rails (~> 3.0)
|
||||||
fssm (0.2.8.1)
|
fssm (0.2.8.1)
|
||||||
gherkin (2.9.1)
|
gherkin (2.9.3)
|
||||||
json (>= 1.4.6)
|
json (>= 1.4.6)
|
||||||
haml (3.1.4)
|
haml (3.1.4)
|
||||||
highline (1.6.11)
|
highline (1.6.11)
|
||||||
@ -188,7 +188,7 @@ GEM
|
|||||||
jquery-rails (1.0.19)
|
jquery-rails (1.0.19)
|
||||||
railties (~> 3.0)
|
railties (~> 3.0)
|
||||||
thor (~> 0.14)
|
thor (~> 0.14)
|
||||||
json (1.6.5)
|
json (1.6.6)
|
||||||
kaminari (0.13.0)
|
kaminari (0.13.0)
|
||||||
actionpack (>= 3.0.0)
|
actionpack (>= 3.0.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
@ -302,10 +302,10 @@ GEM
|
|||||||
polyglot
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
tzinfo (0.3.32)
|
tzinfo (0.3.32)
|
||||||
uglifier (1.2.3)
|
uglifier (1.2.4)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
multi_json (>= 1.0.2)
|
multi_json (>= 1.0.2)
|
||||||
unicorn (4.2.0)
|
unicorn (4.2.1)
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
rack
|
rack
|
||||||
raindrops (~> 0.7)
|
raindrops (~> 0.7)
|
||||||
|
@ -73,18 +73,20 @@ class Locomotive.Views.ContentEntries.FormView extends Locomotive.Views.Shared.F
|
|||||||
new_entry = new Locomotive.Models.ContentEntry(@options["#{name}_new_entry"])
|
new_entry = new Locomotive.Models.ContentEntry(@options["#{name}_new_entry"])
|
||||||
view = new Locomotive.Views.Shared.Fields.HasManyView model: @model, name: name, new_entry: new_entry, inverse_of: inverse_of
|
view = new Locomotive.Views.Shared.Fields.HasManyView model: @model, name: name, new_entry: new_entry, inverse_of: inverse_of
|
||||||
|
|
||||||
@_has_many_field_views.push(view)
|
if view.ui_enabled()
|
||||||
|
@_has_many_field_views.push(view)
|
||||||
|
|
||||||
@$("##{@model.paramRoot}_#{name}_input label").after(view.render().el)
|
@$("##{@model.paramRoot}_#{name}_input label").after(view.render().el)
|
||||||
|
|
||||||
enable_many_to_many_fields: ->
|
enable_many_to_many_fields: ->
|
||||||
_.each @model.get('many_to_many_custom_fields'), (field) =>
|
_.each @model.get('many_to_many_custom_fields'), (field) =>
|
||||||
name = field[0]
|
name = field[0]
|
||||||
view = new Locomotive.Views.Shared.Fields.ManyToManyView model: @model, name: name, all_entries: @options["all_#{name}_entries"]
|
view = new Locomotive.Views.Shared.Fields.ManyToManyView model: @model, name: name, all_entries: @options["all_#{name}_entries"]
|
||||||
|
|
||||||
@_many_to_many_field_views.push(view)
|
if view.ui_enabled()
|
||||||
|
@_many_to_many_field_views.push(view)
|
||||||
|
|
||||||
@$("##{@model.paramRoot}_#{name}_input label").after(view.render().el)
|
@$("##{@model.paramRoot}_#{name}_input label").after(view.render().el)
|
||||||
|
|
||||||
slugify_label_field: ->
|
slugify_label_field: ->
|
||||||
@$('li.input.highlighted > input[type=text]').slugify(target: @$('#content_entry__slug'))
|
@$('li.input.highlighted > input[type=text]').slugify(target: @$('#content_entry__slug'))
|
||||||
|
@ -34,6 +34,9 @@ class Locomotive.Views.Shared.Fields.HasManyView extends Backbone.View
|
|||||||
|
|
||||||
return @
|
return @
|
||||||
|
|
||||||
|
ui_enabled: ->
|
||||||
|
@template()?
|
||||||
|
|
||||||
insert_entries: ->
|
insert_entries: ->
|
||||||
if @collection.length > 0
|
if @collection.length > 0
|
||||||
@collection.each (entry) => @insert_entry(entry)
|
@collection.each (entry) => @insert_entry(entry)
|
||||||
|
@ -39,6 +39,9 @@ class Locomotive.Views.Shared.Fields.ManyToManyView extends Backbone.View
|
|||||||
|
|
||||||
return @
|
return @
|
||||||
|
|
||||||
|
ui_enabled: ->
|
||||||
|
@template()?
|
||||||
|
|
||||||
insert_entries: ->
|
insert_entries: ->
|
||||||
if @collection.length > 0
|
if @collection.length > 0
|
||||||
@collection.each (entry) => @insert_entry(entry)
|
@collection.each (entry) => @insert_entry(entry)
|
||||||
|
@ -43,7 +43,7 @@ module Locomotive
|
|||||||
hash[meth]= (if self.source.custom_fields_methods.include?(meth.to_s)
|
hash[meth]= (if self.source.custom_fields_methods.include?(meth.to_s)
|
||||||
if self.source.is_a_custom_field_many_relationship?(meth.to_s)
|
if self.source.is_a_custom_field_many_relationship?(meth.to_s)
|
||||||
# go deeper
|
# go deeper
|
||||||
self.source.send(meth).map { |entry| entry.to_presenter(:depth => self.depth + 1) }
|
self.source.send(meth).ordered.map { |entry| entry.to_presenter(:depth => self.depth + 1) }
|
||||||
else
|
else
|
||||||
self.source.send(meth) rescue nil
|
self.source.send(meth) rescue nil
|
||||||
end
|
end
|
||||||
|
52
features/public/many_to_many.feature
Normal file
52
features/public/many_to_many.feature
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
Feature: Many to Many Association
|
||||||
|
As a designer
|
||||||
|
In order to make dealing with models easier
|
||||||
|
I want to be able to display other models that have a many to many association
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given I have the site: "test site" set up
|
||||||
|
And I have a custom model named "Articles" with
|
||||||
|
| label | type | required |
|
||||||
|
| Title | string | true |
|
||||||
|
| Body | string | false |
|
||||||
|
And I have a custom model named "Projects" with
|
||||||
|
| label | type | required | target |
|
||||||
|
| Name | string | true | |
|
||||||
|
| Description | text | false | |
|
||||||
|
And I set up a many_to_many relationship between "Articles" and "Projects"
|
||||||
|
And I have entries for "Articles" with
|
||||||
|
| title | body |
|
||||||
|
| Hello world | Lorem ipsum |
|
||||||
|
| Lorem ipsum | Lorem ipsum... |
|
||||||
|
And I have entries for "Projects" with
|
||||||
|
| name | description |
|
||||||
|
| My sexy project | Lorem ipsum |
|
||||||
|
| Foo project | Lorem ipsum... |
|
||||||
|
| Bar project | Lorem ipsum... |
|
||||||
|
| Baz project | Lorem ipsum... |
|
||||||
|
And I attach the "My sexy project" project to the "Hello world" article
|
||||||
|
And I attach the "Baz project" project to the "Hello world" article
|
||||||
|
And I attach the "Foo project" project to the "Hello world" article
|
||||||
|
|
||||||
|
Scenario: Displaying the entries of a many to many association
|
||||||
|
Given a page named "article-projects" with the template:
|
||||||
|
"""
|
||||||
|
{% assign article = contents.articles.first %}
|
||||||
|
<h1>Projects for {{ article.title }}</h1>
|
||||||
|
<ul>
|
||||||
|
{% for project in article.projects %}<li>{{ project.name }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
"""
|
||||||
|
When I view the rendered page at "/article-projects"
|
||||||
|
Then the rendered output should look like:
|
||||||
|
"""
|
||||||
|
|
||||||
|
<h1>Projects for Hello world</h1>
|
||||||
|
<ul>
|
||||||
|
<li>My sexy project</li>
|
||||||
|
<li>Baz project</li>
|
||||||
|
<li>Foo project</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
"""
|
@ -41,7 +41,7 @@ Given %r{^I set up a many_to_many relationship between "([^"]*)" and "([^"]*)"$}
|
|||||||
:label => last_name,
|
:label => last_name,
|
||||||
:type => 'many_to_many',
|
:type => 'many_to_many',
|
||||||
:class_name => last_model.klass_with_custom_fields(:entries).to_s,
|
:class_name => last_model.klass_with_custom_fields(:entries).to_s,
|
||||||
:inverse_of => first_name.singularize.downcase
|
:inverse_of => first_name.pluralize.downcase
|
||||||
})
|
})
|
||||||
|
|
||||||
first_model.save
|
first_model.save
|
||||||
@ -50,12 +50,22 @@ Given %r{^I set up a many_to_many relationship between "([^"]*)" and "([^"]*)"$}
|
|||||||
:label => first_name,
|
:label => first_name,
|
||||||
:type => 'many_to_many',
|
:type => 'many_to_many',
|
||||||
:class_name => first_model.klass_with_custom_fields(:entries).to_s,
|
:class_name => first_model.klass_with_custom_fields(:entries).to_s,
|
||||||
:inverse_of => last_name.singularize.downcase
|
:inverse_of => last_name.pluralize.downcase
|
||||||
})
|
})
|
||||||
|
|
||||||
last_model.save
|
last_model.save
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Given %r{^I attach the "([^"]*)" ([\S]*) to the "([^"]*)" ([\S]*)$} do |target_name, target_model_name, souce_name, source_model_name|
|
||||||
|
target_model = @site.content_types.where(:name => target_model_name.pluralize.capitalize).first
|
||||||
|
source_model = @site.content_types.where(:name => source_model_name.pluralize.capitalize).first
|
||||||
|
|
||||||
|
target_entry = target_model.entries.where(:_slug => target_name.permalink).first
|
||||||
|
source_entry = source_model.entries.where(:_slug => souce_name.permalink).first
|
||||||
|
|
||||||
|
source_entry.send(target_model_name.pluralize.downcase.parameterize('_').to_sym).push(target_entry)
|
||||||
|
end
|
||||||
|
|
||||||
Then /^I should be able to view a paginated list of a has many association$/ do
|
Then /^I should be able to view a paginated list of a has many association$/ do
|
||||||
# Create models
|
# Create models
|
||||||
step %{I have an "Articles" model which has many "Comments"}
|
step %{I have an "Articles" model which has many "Comments"}
|
||||||
|
@ -45,7 +45,7 @@ module Locomotive
|
|||||||
if not @@forbidden_attributes.include?(meth.to_s)
|
if not @@forbidden_attributes.include?(meth.to_s)
|
||||||
value = self._source.send(meth)
|
value = self._source.send(meth)
|
||||||
|
|
||||||
if value.respond_to?(:all)
|
if value.respond_to?(:all) # check for an association
|
||||||
filter_and_order_list(value)
|
filter_and_order_list(value)
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
@ -70,7 +70,7 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
list.ordered
|
list.ordered
|
||||||
end.all
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -30,7 +30,7 @@ Gem::Specification.new do |s|
|
|||||||
s.add_dependency 'mongoid', '~> 2.4.5'
|
s.add_dependency 'mongoid', '~> 2.4.5'
|
||||||
s.add_dependency 'locomotive-mongoid-tree', '~> 0.6.2'
|
s.add_dependency 'locomotive-mongoid-tree', '~> 0.6.2'
|
||||||
|
|
||||||
s.add_dependency 'custom_fields', '~> 2.0.0.rc8'
|
s.add_dependency 'custom_fields', '~> 2.0.0.rc9'
|
||||||
|
|
||||||
s.add_dependency 'kaminari', '~> 0.13.0'
|
s.add_dependency 'kaminari', '~> 0.13.0'
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ describe Locomotive::Liquid::Drops::ContentEntry do
|
|||||||
it 'loops through the list' do
|
it 'loops through the list' do
|
||||||
template = %({% for project in category.projects %}{{ project }},{% endfor %})
|
template = %({% for project in category.projects %}{{ project }},{% endfor %})
|
||||||
|
|
||||||
@list.expects(:ordered).returns(mock('criteria', :all => %w(a b)))
|
@list.expects(:ordered).returns(%w(a b))
|
||||||
|
|
||||||
render(template, { 'category' => @category }).should == 'a,b,'
|
render(template, { 'category' => @category }).should == 'a,b,'
|
||||||
end
|
end
|
||||||
@ -21,7 +21,7 @@ describe Locomotive::Liquid::Drops::ContentEntry do
|
|||||||
it 'filters the list' do
|
it 'filters the list' do
|
||||||
template = %({% with_scope order_by: 'name ASC', active: true %}{% for project in category.projects %}{{ project }},{% endfor %}{% endwith_scope %})
|
template = %({% with_scope order_by: 'name ASC', active: true %}{% for project in category.projects %}{{ project }},{% endfor %}{% endwith_scope %})
|
||||||
|
|
||||||
@list.expects(:order_by).with(['name', 'ASC']).returns(mock('criteria', :all => %w(a b)))
|
@list.expects(:order_by).with(['name', 'ASC']).returns(%w(a b))
|
||||||
@list.expects(:where).with({ 'active' => true }).returns(@list)
|
@list.expects(:where).with({ 'active' => true }).returns(@list)
|
||||||
|
|
||||||
render(template, { 'category' => @category }).should == 'a,b,'
|
render(template, { 'category' => @category }).should == 'a,b,'
|
||||||
@ -30,7 +30,7 @@ describe Locomotive::Liquid::Drops::ContentEntry do
|
|||||||
it 'filters the list and uses the default order' do
|
it 'filters the list and uses the default order' do
|
||||||
template = %({% with_scope active: true %}{% for project in category.projects %}{{ project }},{% endfor %}{% endwith_scope %})
|
template = %({% with_scope active: true %}{% for project in category.projects %}{{ project }},{% endfor %}{% endwith_scope %})
|
||||||
|
|
||||||
@list.expects(:ordered).returns(mock('criteria', :all => %w(a b)))
|
@list.expects(:ordered).returns(%w(a b))
|
||||||
@list.expects(:where).with({ 'active' => true }).returns(@list)
|
@list.expects(:where).with({ 'active' => true }).returns(@list)
|
||||||
|
|
||||||
render(template, { 'category' => @category }).should == 'a,b,'
|
render(template, { 'category' => @category }).should == 'a,b,'
|
||||||
|
Loading…
Reference in New Issue
Block a user