atrium 0.0.1.alpha → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/GETTING_STARTED.textile +50 -57
- data/Gemfile.lock +2 -0
- data/README.mkd +30 -20
- data/ROADMAP.mkd +92 -0
- data/app/assets/javascripts/atrium/atrium.js +19 -0
- data/app/assets/stylesheets/atrium/atrium.css +2 -0
- data/app/controllers/atrium/collections_controller.rb +2 -12
- data/app/controllers/atrium/exhibits_controller.rb +5 -17
- data/app/controllers/atrium/showcases_controller.rb +21 -73
- data/app/models/atrium/showcase.rb +6 -0
- data/app/views/atrium/collections/_form.html.erb +12 -7
- data/app/views/atrium/collections/_navigation.html.erb +30 -25
- data/app/views/atrium/collections/edit.html.erb +1 -0
- data/app/views/atrium/collections/show.html.erb +9 -0
- data/app/views/atrium/descriptions/index.html.erb +4 -0
- data/app/views/atrium/exhibits/_form.html.erb +8 -1
- data/app/views/atrium/exhibits/_navigation.html.erb +30 -0
- data/app/views/atrium/exhibits/show.html.erb +9 -1
- data/app/views/atrium/showcases/show.html.erb +1 -1
- data/app/views/catalog/index.html.erb +7 -1
- data/app/views/layouts/atrium.html.erb +3 -27
- data/app/views/shared/_collection_search_form.html.erb +1 -1
- data/app/views/shared/_featured_sources.html.erb +3 -0
- data/app/views/shared/_list_descriptions.html.erb +3 -2
- data/atrium.gemspec +2 -4
- data/lib/atrium/atrium_helper_behavior.rb +3 -6
- data/lib/atrium/catalog.rb +1 -1
- data/lib/atrium/collections_helper.rb +33 -0
- data/lib/atrium/descriptions_helper.rb +4 -0
- data/lib/atrium/routes.rb +2 -1
- data/lib/atrium/solr_helper.rb +4 -4
- data/lib/atrium/version.rb +1 -1
- data/test_support/spec/controllers/atrium/showcases_controller_spec.rb +34 -0
- data/test_support/spec/helpers/atrium_solr_helper_spec.rb +16 -6
- metadata +184 -171
data/GETTING_STARTED.textile
CHANGED
@@ -1,74 +1,72 @@
|
|
1
|
-
h1.
|
1
|
+
h1. Atrium
|
2
|
+
|
3
|
+
Atrium is a Ruby-on-Rails 3 gem containing the core code for a web application to build collection based of blacklight which build faceted search and discovery layer on top of solr
|
2
4
|
|
3
5
|
h2. Before You Begin
|
4
6
|
|
5
7
|
*!!! This is a WORK IN PROGRESS !!!*
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
h1. Atrium
|
10
|
-
|
11
|
-
Atrium is a Rails Engines plugin containing the core code for a Atrium application. The full hydra stack includes the following:
|
9
|
+
h2. Installation/Setup
|
12
10
|
|
13
|
-
|
14
|
-
- "Solr":http://lucene.apache.org/solr/ (a java application, also ported to other languages) for the Search Engine
|
15
|
-
- Atrium (a rails engines plugin) to create collection, exhibit and showcase base on the blacklight configuration
|
11
|
+
h3. Installation Prerequisites
|
16
12
|
|
17
13
|
|
18
|
-
|
14
|
+
Ruby 1.8.7 is required by Atrium release 4.0; RVM is strongly suggested.
|
19
15
|
|
20
|
-
|
16
|
+
h3. Install Rails
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
Currently Atrium is compatible with Rails 3.1
|
18
|
+
Currently Atrium is compatible with Rails 3.2
|
25
19
|
|
26
20
|
<pre>
|
27
|
-
gem install 'rails' --version '~>3.
|
28
|
-
gem install 'bundler'
|
21
|
+
gem install 'rails' --version '~>3.2.2'
|
29
22
|
</pre>
|
30
23
|
|
31
24
|
h3. Generate a new rails application:
|
32
25
|
|
33
26
|
<pre>
|
34
|
-
rails new
|
35
|
-
cd
|
27
|
+
rails new my_atrium_app
|
28
|
+
cd my_atrium_app
|
36
29
|
</pre>
|
37
30
|
|
38
31
|
h3. Install Dependencies
|
39
32
|
|
40
|
-
First, add them to the "Gemfile":http://gembundler.com/gemfile.html of your application:
|
33
|
+
First, add them to the "Gemfile":http://gembundler.com/gemfile.html of your application. You may already have a Gemfile in the new rails application you just generated; in that case, be sure to add blacklight devise and the development/test group per below:
|
41
34
|
|
42
35
|
<pre>
|
43
|
-
source 'http://rubygems.org'
|
44
|
-
|
45
|
-
gem 'rails', '~>3.
|
46
|
-
|
47
|
-
gem '
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
gem '
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
36
|
+
source 'http://rubygems.org'
|
37
|
+
|
38
|
+
gem 'rails', '~> 3.2'
|
39
|
+
gem 'blacklight', '~> 3.3'
|
40
|
+
gem 'atrium', :path => '../../'
|
41
|
+
|
42
|
+
gem 'cancan'
|
43
|
+
gem 'jquery-rails'
|
44
|
+
gem 'json'
|
45
|
+
|
46
|
+
group :assets do
|
47
|
+
gem 'coffee-rails', '~> 3.2.1'
|
48
|
+
gem 'sass-rails', '~> 3.2.3'
|
49
|
+
gem 'therubyracer', :platforms => :ruby
|
50
|
+
gem 'uglifier', '>= 1.0.3'
|
51
|
+
end
|
52
|
+
|
53
|
+
# For testing
|
54
|
+
group :development, :test do
|
55
|
+
gem 'bcrypt-ruby'
|
56
|
+
gem 'capybara'
|
57
|
+
gem 'cucumber-rails'
|
58
|
+
gem 'database_cleaner'
|
59
|
+
gem 'factory_girl', '~> 1.1'
|
60
|
+
gem 'mocha'
|
61
|
+
gem 'rspec'
|
62
|
+
gem 'rspec-rails', '>=2.5.0'
|
63
|
+
gem 'ruby-debug'
|
64
|
+
gem 'sqlite3'
|
65
|
+
end
|
66
|
+
gem "devise"
|
67
|
+
gem "compass-rails", "~> 1.0.0", :group => :assets
|
68
|
+
gem "compass-susy-plugin", "~> 0.9.0", :group => :assets
|
69
|
+
|
72
70
|
</pre>
|
73
71
|
|
74
72
|
To install all of the dependencies, run:
|
@@ -81,11 +79,7 @@ On some systems, you will have to install system libraries that various gems rel
|
|
81
79
|
|
82
80
|
h3. Run the generators and migrations:
|
83
81
|
|
84
|
-
Run the
|
85
|
-
|
86
|
-
<pre>rails g blacklight --devise</pre>
|
87
|
-
|
88
|
-
Run the atrium generator
|
82
|
+
Run the Atrium generator
|
89
83
|
|
90
84
|
<pre>rails g atrium -df</pre>
|
91
85
|
|
@@ -98,12 +92,11 @@ rake db:test:prepare
|
|
98
92
|
|
99
93
|
h3. You're done.
|
100
94
|
|
101
|
-
Congratulations. You've set up the code
|
102
|
-
|
103
|
-
Read "Tools for Developing and Testing":http://hudson.projecthydra.org/job/hydra-head-rails3-plugin/Documentation/file.Tools.html, then read "How to Get Started":http://hudson.projecthydra.org/job/hydra-head-rails3-plugin/Documentation/file.HOW_TO_GET_STARTED.html to get a sense of what you can do with your Hydra Head.
|
95
|
+
Congratulations. You've set up the code to create atrium application.
|
104
96
|
|
105
97
|
h2. Modifying and Testing the Atrium Gem
|
106
98
|
|
107
|
-
#TODO
|
108
99
|
|
109
100
|
h2. Acknowledgements
|
101
|
+
|
102
|
+
h3. Design & Strategic Contributions
|
data/Gemfile.lock
CHANGED
@@ -251,6 +251,7 @@ GEM
|
|
251
251
|
ruby-debug-base (~> 0.10.4.0)
|
252
252
|
ruby-debug-base (0.10.4)
|
253
253
|
linecache (>= 0.3)
|
254
|
+
ruby_gntp (0.3.4)
|
254
255
|
rubyzip (0.9.5)
|
255
256
|
sanitize (2.0.3)
|
256
257
|
nokogiri (>= 1.4.4, < 1.6)
|
@@ -317,4 +318,5 @@ DEPENDENCIES
|
|
317
318
|
rspec-rails (>= 2.0.0)
|
318
319
|
ruby-debug
|
319
320
|
ruby-debug-base
|
321
|
+
ruby_gntp
|
320
322
|
sqlite3
|
data/README.mkd
CHANGED
@@ -1,56 +1,66 @@
|
|
1
1
|
# Atrium
|
2
2
|
|
3
|
-
|
4
|
-
promised functionality to exist.__
|
3
|
+
## A note from the developers
|
5
4
|
|
5
|
+
_0.0.1 is an alpha release. Treat it accordingly_
|
6
6
|
|
7
|
-
|
7
|
+
_"master" is going through a major refactor. THINGS MAY BREAK. THE WORLD MAY
|
8
|
+
END_
|
9
|
+
|
10
|
+
Atrium is a project that has been gestating for a while. Consider the present
|
11
|
+
state of the code a proof-of-concept implementation. There are lots of things we
|
12
|
+
would do differently if we started over again. For more information see
|
13
|
+
`ROADMAP.mkd`. The development process is coordinated in a [public-facing
|
14
|
+
JIRA][1]
|
8
15
|
|
9
|
-
|
16
|
+
## What it's for
|
10
17
|
|
11
|
-
|
12
|
-
- adding context
|
18
|
+
Atrium is a tool for extending a [Blacklight][2]-enabled application by:
|
13
19
|
|
14
|
-
|
20
|
+
- Grouping items
|
21
|
+
- Adding context
|
22
|
+
- Customizing presentation
|
15
23
|
|
16
|
-
Atrium provides
|
24
|
+
Atrium provides four mechanisms to achieve this end:
|
17
25
|
|
18
26
|
- Collections
|
19
27
|
- Exhibits
|
20
28
|
- Showcases
|
21
|
-
|
29
|
+
- Themes
|
22
30
|
|
23
31
|
### Collections
|
24
|
-
|
25
32
|
A collection contains a subset of the items in the complete index as defined by
|
26
33
|
a Solr query. An explicitly declared subset of the total facets can be applied
|
27
34
|
to these items. A collection description and or featured items form the
|
28
35
|
collection can be displayed at the top level collection page. Collections can be
|
29
36
|
themed independently of the base application and other collections.
|
30
37
|
|
31
|
-
|
32
38
|
### Exhibits
|
33
|
-
|
34
39
|
An exhibit is a customizable view of a single topic (as defined by a facet),
|
35
40
|
further scoped by an optional Solr query. An exhibit defines it's own
|
36
41
|
hierarchical list of facets. An exhibit may also have a description and a list
|
37
42
|
of featured items.
|
38
43
|
|
39
|
-
|
40
44
|
### Showcases
|
41
|
-
|
42
45
|
A showcase is a container for storing feature items and descriptions. A showcase
|
43
46
|
can be attached to a collection, exhibit, or to specific combinations of
|
44
47
|
selected facets and facet values within an exhibit. There can be multiple
|
45
48
|
showcases in an exhibit.
|
46
49
|
|
50
|
+
### Themes
|
51
|
+
At present, themes are a wrapper around the existing rails templating system. A
|
52
|
+
theme is simply a [nested layout][3] that works in conjunction with some `yeild`
|
53
|
+
blocks in the base atrium layout. This is a pretty flexible solution but
|
54
|
+
requires the implementer to know how layouts and rendering work in Rails. It
|
55
|
+
also means you have to re-deploy the application every time you want to change
|
56
|
+
how it looks.
|
47
57
|
|
48
58
|
## Acknowledgements
|
49
|
-
|
50
|
-
Thanks to [Hiten Parmar][2] for the gem name. The [origional atirum gem][3] was
|
59
|
+
Thanks to [Hiten Parmar][4] for the gem name. The [original atrium gem][5] was
|
51
60
|
an instant web server.
|
52
61
|
|
53
|
-
|
54
|
-
[
|
55
|
-
[
|
56
|
-
[
|
62
|
+
[1]: https://jira.duraspace.org/browse/HYGALL
|
63
|
+
[2]: https://github.com/projectblacklight/blacklight
|
64
|
+
[3]: http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts
|
65
|
+
[4]: http://www.hitenparmar.com/
|
66
|
+
[5]: https://github.com/hrp/atrium
|
data/ROADMAP.mkd
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Development Roadmap
|
2
|
+
|
3
|
+
The following issues need to be addressed before it would be considered a 1.0
|
4
|
+
release candidate:
|
5
|
+
|
6
|
+
### Atrium should be a mountable Rails engine -- but isn't
|
7
|
+
Atrium was based on an early version of [hydra-head][1] which, in turn, shared
|
8
|
+
code with [Blacklight][5] which was a Rails 2 plugin at the time. As such the
|
9
|
+
integration points between Atrium and the host Rails application are not
|
10
|
+
following the present best practices. Atrium should be refactored to be an
|
11
|
+
[isolated engine][2].
|
12
|
+
|
13
|
+
### Atrium overrides and extends the Blacklight catalog a lot -- and shouldn't
|
14
|
+
Parts of Atrium rely on the Blacklight catalog controller to return collections
|
15
|
+
of Solr documents. This is a messy process and tightly couples Atrium to
|
16
|
+
Blacklight in undesirable ways. Now that [Blacklight][5] provides Solr helper
|
17
|
+
methods for both the Lucene query handler as well as the DisMax query handler we
|
18
|
+
should be able to avoid this problem.
|
19
|
+
|
20
|
+
### The routs are ugly
|
21
|
+
The routes of an application is it's public API. They should be human-readable
|
22
|
+
and should try to conform to be [resourceful][3] whenever possible. The routes
|
23
|
+
in Atrium will be overhauled when the gem is converted to a modern Rails engine.
|
24
|
+
The days of `/atrium_*` are numbered. Bonus points if collections have a
|
25
|
+
[frendliy_id][4] style identifier. See `doc/Routing.mdown` for more.
|
26
|
+
|
27
|
+
### Keeping track of the internal application state is fragile
|
28
|
+
The application behaves as it should under normal circumstances but it lacks
|
29
|
+
resilience. This stems from the complexity of interacting with the same data in
|
30
|
+
Atrium in several modes of operation:
|
31
|
+
- Searching the entire holdings
|
32
|
+
- Searching a collection
|
33
|
+
- Browsing a collection
|
34
|
+
- Modifying a collection while searching
|
35
|
+
- Modifying a collection while browsing
|
36
|
+
- Selecting items within a collection in a modal window
|
37
|
+
- Setting a scope within the holdings for a collection
|
38
|
+
- Setting a scope within a collection for an exhibit
|
39
|
+
Determining which of these states the user is presently in is accomplished with
|
40
|
+
a combination of session storage and passing params around in the URL. The
|
41
|
+
resulting experience doesn't inspire confidence. Params can accumulate
|
42
|
+
unintentionally. Session variables change while interacting with the site in
|
43
|
+
more than one browser tab. It isn't always clear why things are the way they are
|
44
|
+
now.
|
45
|
+
|
46
|
+
Some of these issues may be able to be addressed with better routes but
|
47
|
+
preventing these kinds of problems entirely will require refactoring a lot of
|
48
|
+
the application logic to make stateless interactions possible.
|
49
|
+
|
50
|
+
### The management interface is confusing
|
51
|
+
There is a collision of concerns when managing a collection and the exhibits and
|
52
|
+
showcases it contains. Keeping all of the possible customizations straight and
|
53
|
+
conveying _what they actually mean_ hasn't been done effectively. There are lots
|
54
|
+
of little changes that could be made to the present interface that would make a
|
55
|
+
difference but more dramatic refactoring may be required to achieve the desired
|
56
|
+
result.
|
57
|
+
|
58
|
+
### The theming and templating options are underwhelming
|
59
|
+
In order to make significant changes in the look and feel of a collection in
|
60
|
+
Atrium you will need to know HTML, CSS, be familiar with [how Rails renders
|
61
|
+
views][6], understand how to configure [Blacklight][5], and have a working
|
62
|
+
knowledge how to index things into Solr. That's a pretty high barrier to entry.
|
63
|
+
This isn't necessarily a problem if Atrium is a toolkit for developers familiar
|
64
|
+
with Blacklight who are creating digital exhibits. However, if Atrium would like
|
65
|
+
to provide a turn-key solution that can be easily customized from within the
|
66
|
+
application by someone without a firm grasp of web technologies then we have a
|
67
|
+
long way to go.
|
68
|
+
|
69
|
+
Allowing the look and feel of a collection to be significantly modified from the
|
70
|
+
frontend itself would require a lot of work. Our best guess as to how this
|
71
|
+
problem should be approached is by adding another templating layer in the view
|
72
|
+
rendering stack. Development stalled on this over concerns about the feasibility
|
73
|
+
of rendering the contents of Blacklight partials in custom Liquid tags. We
|
74
|
+
should be able to get this approach to work for the browse views as long as
|
75
|
+
we're relying on Blacklight to just provide collections of Solr documents. See
|
76
|
+
`doc/Theming.mdown` for more.
|
77
|
+
|
78
|
+
The [Asset Pipeline][7] is great but because assets should be pre-compiled for
|
79
|
+
production use we would have to support an alternative solution for providing
|
80
|
+
custom, collection-specific CSS.
|
81
|
+
|
82
|
+
It boils down to choosing the audience that Atrium is trying to serve. Should we
|
83
|
+
even be trying to compete with [Omeka][8]?
|
84
|
+
|
85
|
+
[1]: https://github.com/projecthydra/hydra-head
|
86
|
+
[2]: http://api.rubyonrails.org/classes/Rails/Engine.html#label-Isolated+Engine
|
87
|
+
[3]: https://rubygems.org/gems/friendly_id
|
88
|
+
[4]: http://guides.rubyonrails.org/routing.html#resources-on-the-web
|
89
|
+
[5]: https://github.com/projectblacklight/blacklight
|
90
|
+
[6]: http://guides.rubyonrails.org/layouts_and_rendering.html
|
91
|
+
[7]: http://guides.rubyonrails.org/asset_pipeline.html
|
92
|
+
[8]: http://omeka.org/
|
@@ -164,6 +164,25 @@
|
|
164
164
|
});
|
165
165
|
});
|
166
166
|
|
167
|
+
$("a.remove_featured", this).live("click", function(e) {
|
168
|
+
var $docNode = $(this).closest('div.document')
|
169
|
+
var url = $(this).attr('action');
|
170
|
+
$.ajax({
|
171
|
+
type: "POST",
|
172
|
+
url: url,
|
173
|
+
dataType: "html",
|
174
|
+
beforeSend: function() {
|
175
|
+
$docNode.animate({'backgroundColor':'#fb6c6c'},300);
|
176
|
+
},
|
177
|
+
success: function(data) {
|
178
|
+
$docNode.slideUp(300,function() {
|
179
|
+
$docNode.remove();
|
180
|
+
});
|
181
|
+
//$("#show-selected").before('<div id="flash_notice"> data </div>'); // This could be implemented better
|
182
|
+
}
|
183
|
+
});
|
184
|
+
});
|
185
|
+
|
167
186
|
$('.edit-text').editable(submitEditableText,{
|
168
187
|
indicator : 'Saving...',
|
169
188
|
tooltip : 'Click to edit...'
|
@@ -21,7 +21,6 @@ class Atrium::CollectionsController < Atrium::BaseController
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def set_collection_scope
|
24
|
-
logger.error("into scoping")
|
25
24
|
session[:copy_folder_document_ids] = session[:folder_document_ids]
|
26
25
|
session[:folder_document_ids] = []
|
27
26
|
@atrium_collection = Atrium::Collection.find(params[:id])
|
@@ -52,21 +51,12 @@ class Atrium::CollectionsController < Atrium::BaseController
|
|
52
51
|
@atrium_collection= Atrium::Collection.find(params[:id])
|
53
52
|
@atrium_showcase= Atrium::Showcase.with_selected_facets(@atrium_collection.id,@atrium_collection.class.name, params[:f]).first
|
54
53
|
end
|
55
|
-
|
56
|
-
if @atrium_collection && @atrium_collection.filter_query_params && @atrium_collection.filter_query_params[:solr_doc_ids]
|
57
|
-
|
58
|
-
items_document_ids = @atrium_collection.filter_query_params[:solr_doc_ids].split(',')
|
59
|
-
@collection_items_response, @collection_items_documents = get_solr_response_for_field_values("id",items_document_ids || [])
|
60
|
-
end
|
54
|
+
@collection_items_response, @collection_items_documents=get_solr_documents_from_asset(@atrium_collection)
|
61
55
|
if(params[:showcase_id] && @atrium_showcase.nil?)
|
62
56
|
@atrium_showcase = Atrium::Showcase.find(params[:showcase_id])
|
63
57
|
end
|
64
|
-
|
65
|
-
selected_document_ids = @atrium_showcase.showcase_items[:solr_doc_ids].split(',')
|
66
|
-
@featured_response, @featured_documents = get_solr_response_for_field_values("id",selected_document_ids || [])
|
67
|
-
end
|
58
|
+
@featured_response, @featured_documents=get_solr_documents_from_asset(@atrium_showcase) unless @atrium_showcase.nil?
|
68
59
|
@description_hash=get_description_for_showcase(@atrium_showcase) unless @atrium_showcase.nil?
|
69
|
-
|
70
60
|
end
|
71
61
|
|
72
62
|
def edit
|
@@ -34,23 +34,11 @@ class Atrium::ExhibitsController < Atrium::BaseController
|
|
34
34
|
def show
|
35
35
|
#get children of emission dates
|
36
36
|
@members = get_all_children(@browse_document_list, "is_member_of_s")
|
37
|
-
@exhibit= Atrium::Exhibit.find(params[:id])
|
37
|
+
@exhibit= Atrium::Exhibit.find(params[:id]) unless @exhibit
|
38
38
|
@exhibit_navigation_data = get_exhibit_navigation_data
|
39
|
-
|
40
|
-
|
41
|
-
items_document_ids = @exhibit.filter_query_params[:solr_doc_ids].split(',')
|
42
|
-
|
43
|
-
@collection_items_response, @collection_items_documents = get_solr_response_for_field_values("id",items_document_ids || [])
|
44
|
-
end
|
45
|
-
|
46
|
-
|
39
|
+
@collection_items_response, @collection_items_documents=get_solr_documents_from_asset(@exhibit)
|
47
40
|
@atrium_showcase=Atrium::Showcase.with_selected_facets(@exhibit.id, @exhibit.class.name, params[:f]).first
|
48
|
-
|
49
|
-
|
50
|
-
selected_document_ids = @atrium_showcase.showcase_items[:solr_doc_ids].split(',')
|
51
|
-
|
52
|
-
@featured_response, @featured_documents = get_solr_response_for_field_values("id",selected_document_ids || [])
|
53
|
-
end
|
41
|
+
@featured_response, @featured_documents=get_solr_documents_from_asset(@atrium_showcase) unless @atrium_showcase.nil?
|
54
42
|
@description_hash=get_description_for_showcase(@atrium_showcase) unless @atrium_showcase.nil?
|
55
43
|
if params[:no_layout]
|
56
44
|
render :layout=>false
|
@@ -99,8 +87,8 @@ private
|
|
99
87
|
|
100
88
|
def determine_collection_id
|
101
89
|
if params[:id]
|
102
|
-
exhibit = Atrium::Exhibit.find(params[:id])
|
103
|
-
collection_id = exhibit.atrium_collection_id if exhibit
|
90
|
+
@exhibit = Atrium::Exhibit.find(params[:id])
|
91
|
+
collection_id = @exhibit.atrium_collection_id if @exhibit
|
104
92
|
end
|
105
93
|
return collection_id
|
106
94
|
end
|