iqvoc 4.0.9 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +12 -0
  3. data/Gemfile +8 -6
  4. data/Gemfile.lock +56 -36
  5. data/README.md +3 -7
  6. data/app/controllers/concepts/hierarchical_controller.rb +2 -5
  7. data/app/controllers/concepts/scheme_controller.rb +51 -0
  8. data/app/controllers/concepts_controller.rb +2 -0
  9. data/app/controllers/hierarchy_controller.rb +105 -0
  10. data/app/controllers/rdf_controller.rb +0 -10
  11. data/app/controllers/user_sessions_controller.rb +5 -1
  12. data/app/helpers/application_helper.rb +1 -1
  13. data/app/helpers/concepts_helper.rb +19 -0
  14. data/app/helpers/rdf_helper.rb +5 -0
  15. data/app/models/concept/base.rb +10 -1
  16. data/app/models/concept/relation/skos/base.rb +8 -1
  17. data/app/models/concept/skos/scheme.rb +54 -13
  18. data/app/models/concept/validations.rb +2 -2
  19. data/app/models/labeling/base.rb +8 -0
  20. data/app/models/labeling/skos/base.rb +0 -8
  21. data/app/models/notation/base.rb +59 -0
  22. data/app/views/concepts/_form.html.erb +9 -1
  23. data/app/views/concepts/scheme/_sidebar.html.erb +6 -0
  24. data/app/views/concepts/scheme/edit.html.erb +30 -0
  25. data/app/views/concepts/scheme/show.html.erb +19 -0
  26. data/app/views/{rdf/scheme.iqrdf → concepts/scheme/show.iqrdf} +0 -0
  27. data/app/views/hierarchy/show.html.erb +5 -0
  28. data/app/views/hierarchy/show.iqrdf +24 -0
  29. data/app/views/partials/notation/_base.html.erb +8 -0
  30. data/app/views/partials/notation/_edit_base.html.erb +18 -0
  31. data/config/application.rb +2 -0
  32. data/config/engine.rb +0 -1
  33. data/config/initializers/mime_types.rb +2 -2
  34. data/config/locales/activerecord.de.yml +8 -0
  35. data/config/locales/activerecord.en.yml +8 -0
  36. data/config/locales/activerecord.pt.yml +8 -0
  37. data/config/locales/de.yml +5 -1
  38. data/config/locales/en.yml +5 -1
  39. data/config/locales/pt.yml +5 -1
  40. data/config/routes.rb +35 -32
  41. data/db/migrate/20130315093255_add_notations.rb +9 -0
  42. data/db/migrate/20130315141952_add_indexes_to_notations.rb +5 -0
  43. data/db/schema.rb +9 -1
  44. data/iqvoc.gemspec +0 -1
  45. data/lib/generators/app/template.rb +3 -0
  46. data/lib/iqvoc/ability.rb +3 -1
  47. data/lib/iqvoc/configuration/concept.rb +10 -1
  48. data/lib/iqvoc/configuration/core.rb +4 -0
  49. data/lib/iqvoc/rdfapi.rb +1 -0
  50. data/lib/iqvoc/skos_importer.rb +14 -7
  51. data/lib/iqvoc/version.rb +1 -1
  52. data/test/functional/hierarchy_test.rb +355 -0
  53. data/test/integration/client_edit_concept_test.rb +1 -1
  54. data/test/integration/concept_scheme_test.rb +38 -5
  55. data/test/unit/concept_scheme_test.rb +35 -0
  56. data/test/unit/skos_import_test.rb +29 -2
  57. metadata +40 -64
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 16d4accd1ec6444487808f8bd96d5c199ab71eff
4
+ data.tar.gz: 6207cec740aa1379da5c2416a825a08e63ef472b
5
+ SHA512:
6
+ metadata.gz: 562c550eb713e0372b0bc67a7c7d34518460f03ccf35345a486237f1691a3337c9c44593ad25487c72e07e0703d200261c9258d13f41d9003dffa411ff3980bc
7
+ data.tar.gz: ffda6405a0ba2955b29e4b110ddb35d8fa016bbbd5bbc26215cafb9fff52b4a7eb1bb4664506a4255b58b245c4ed80cdd5d03de54e24a18917848f4676300898
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [4.1.0]
2
+
3
+ * Concepts hierarchy API (/hierarchy)
4
+ * Support for SKOS notations
5
+ * Adjusted RDF serializations to always include related concepts' pref. labels
6
+ * Fixed MIME type for RDF/XML
7
+ * Editable concept scheme
8
+ * Ruby 2.0 compatibility
9
+ * Dropped support for Ruby 1.8
10
+ * Heroku Cedar support
11
+ * Bugfixes
12
+
1
13
  ## [4.0.9]
2
14
 
3
15
  * Speed improvements in SKOS importer
data/Gemfile CHANGED
@@ -19,7 +19,7 @@ source 'http://rubygems.org'
19
19
  # TODO: The following dependencies could be included by the "gemspec" command.
20
20
  # There is only one problem: gemspec puts the dependencies automatically to a
21
21
  # group (:development by default). This is not what we need.
22
- gem 'rails', '3.2.12'
22
+ gem 'rails', '3.2.13'
23
23
 
24
24
  group :assets do
25
25
  gem 'uglifier', '>= 1.0.3'
@@ -36,7 +36,6 @@ gem 'json'
36
36
  gem 'rails_autolink'
37
37
  gem 'jruby-openssl', :platforms => :jruby
38
38
  gem 'simple_form'
39
- gem 'fastercsv', :platforms => :ruby_18
40
39
 
41
40
  group :development do
42
41
  gem 'heroku'
@@ -47,12 +46,17 @@ end
47
46
 
48
47
  group :development, :test do
49
48
  gem 'awesome_print'
50
- gem 'pry', :platform => :ruby
51
- gem 'pry-remote', :platform => :ruby
52
49
 
53
50
  platforms :ruby do
54
51
  gem 'mysql2'
55
52
  gem 'sqlite3'
53
+
54
+ gem 'pry'
55
+ gem 'pry-rails'
56
+ gem 'pry-debugger'
57
+ gem 'pry-remote'
58
+ gem 'hirb-unicode'
59
+ gem 'cane'
56
60
  end
57
61
 
58
62
  platforms :jruby do
@@ -76,8 +80,6 @@ group :test do
76
80
  end
77
81
 
78
82
  group :production do
79
- gem 'sqlite3', :platforms => :ruby
80
- gem 'activerecord-oracle_enhanced-adapter', :platforms => :jruby
81
83
  end
82
84
 
83
85
  group :heroku do
data/Gemfile.lock CHANGED
@@ -1,12 +1,12 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- actionmailer (3.2.12)
5
- actionpack (= 3.2.12)
6
- mail (~> 2.4.4)
7
- actionpack (3.2.12)
8
- activemodel (= 3.2.12)
9
- activesupport (= 3.2.12)
4
+ actionmailer (3.2.13)
5
+ actionpack (= 3.2.13)
6
+ mail (~> 2.5.3)
7
+ actionpack (3.2.13)
8
+ activemodel (= 3.2.13)
9
+ activesupport (= 3.2.13)
10
10
  builder (~> 3.0.0)
11
11
  erubis (~> 2.7.0)
12
12
  journey (~> 1.0.4)
@@ -14,12 +14,12 @@ GEM
14
14
  rack-cache (~> 1.2)
15
15
  rack-test (~> 0.6.1)
16
16
  sprockets (~> 2.2.1)
17
- activemodel (3.2.12)
18
- activesupport (= 3.2.12)
17
+ activemodel (3.2.13)
18
+ activesupport (= 3.2.13)
19
19
  builder (~> 3.0.0)
20
- activerecord (3.2.12)
21
- activemodel (= 3.2.12)
22
- activesupport (= 3.2.12)
20
+ activerecord (3.2.13)
21
+ activemodel (= 3.2.13)
22
+ activesupport (= 3.2.13)
23
23
  arel (~> 3.0.2)
24
24
  tzinfo (~> 0.3.29)
25
25
  activerecord-jdbc-adapter (1.2.2)
@@ -29,12 +29,11 @@ GEM
29
29
  activerecord-jdbcsqlite3-adapter (1.2.2)
30
30
  activerecord-jdbc-adapter (~> 1.2.2)
31
31
  jdbc-sqlite3 (~> 3.7.2)
32
- activerecord-oracle_enhanced-adapter (1.4.1)
33
- activeresource (3.2.12)
34
- activemodel (= 3.2.12)
35
- activesupport (= 3.2.12)
36
- activesupport (3.2.12)
37
- i18n (~> 0.6)
32
+ activeresource (3.2.13)
33
+ activemodel (= 3.2.13)
34
+ activesupport (= 3.2.13)
35
+ activesupport (3.2.13)
36
+ i18n (= 0.6.1)
38
37
  multi_json (~> 1.0)
39
38
  addressable (2.3.3)
40
39
  ansi (1.4.3)
@@ -51,6 +50,8 @@ GEM
51
50
  bouncy-castle-java (1.5.0146.1)
52
51
  builder (3.0.4)
53
52
  cancan (1.6.8)
53
+ cane (2.5.2)
54
+ parallel
54
55
  capybara (2.0.2)
55
56
  mime-types (>= 1.16)
56
57
  nokogiri (>= 1.3.3)
@@ -66,9 +67,16 @@ GEM
66
67
  childprocess (0.3.8)
67
68
  ffi (~> 1.0, >= 1.0.11)
68
69
  coderay (1.0.8)
70
+ columnize (0.3.6)
69
71
  crack (0.3.1)
70
72
  database_cleaner (0.8.0)
71
73
  debug_inspector (0.0.2)
74
+ debugger (1.5.0)
75
+ columnize (>= 0.3.1)
76
+ debugger-linecache (~> 1.2.0)
77
+ debugger-ruby_core_source (~> 1.2.0)
78
+ debugger-linecache (1.2.0)
79
+ debugger-ruby_core_source (1.2.0)
72
80
  erubis (2.7.0)
73
81
  excon (0.16.2)
74
82
  execjs (1.4.0)
@@ -78,7 +86,6 @@ GEM
78
86
  factory_girl_rails (4.1.0)
79
87
  factory_girl (~> 4.1.0)
80
88
  railties (>= 3.0.0)
81
- fastercsv (1.5.5)
82
89
  ffi (1.1.5)
83
90
  ffi (1.1.5-java)
84
91
  heroku (2.31.2)
@@ -90,6 +97,10 @@ GEM
90
97
  heroku-api (0.3.5)
91
98
  excon (~> 0.16.1)
92
99
  hike (1.2.1)
100
+ hirb (0.7.1)
101
+ hirb-unicode (0.0.5)
102
+ hirb (~> 0.5)
103
+ unicode-display_width (~> 0.1.1)
93
104
  i18n (0.6.1)
94
105
  iq_rdf (0.1.8)
95
106
  builder
@@ -112,24 +123,30 @@ GEM
112
123
  ffi (~> 1.1.1)
113
124
  spoon (~> 0.0.1)
114
125
  libv8 (3.3.10.4)
115
- mail (2.4.4)
126
+ mail (2.5.3)
116
127
  i18n (>= 0.4.0)
117
128
  mime-types (~> 1.16)
118
129
  treetop (~> 1.4.8)
119
130
  method_source (0.8.1)
120
131
  mime-types (1.21)
121
132
  minitest (3.4.0)
122
- multi_json (1.6.1)
133
+ multi_json (1.7.2)
123
134
  mysql2 (0.3.11)
124
135
  netrc (0.7.7)
125
136
  nokogiri (1.5.6)
126
137
  nokogiri (1.5.6-java)
138
+ parallel (0.6.4)
127
139
  pg (0.14.1)
128
140
  polyglot (0.3.3)
129
141
  pry (0.9.10)
130
142
  coderay (~> 1.0.5)
131
143
  method_source (~> 0.8)
132
144
  slop (~> 3.3.1)
145
+ pry-debugger (0.2.2)
146
+ debugger (~> 1.3)
147
+ pry (~> 0.9.10)
148
+ pry-rails (0.2.2)
149
+ pry (>= 0.9.10)
133
150
  pry-remote (0.1.6)
134
151
  pry (~> 0.9)
135
152
  slop (~> 3.0)
@@ -140,25 +157,25 @@ GEM
140
157
  rack
141
158
  rack-test (0.6.2)
142
159
  rack (>= 1.0)
143
- rails (3.2.12)
144
- actionmailer (= 3.2.12)
145
- actionpack (= 3.2.12)
146
- activerecord (= 3.2.12)
147
- activeresource (= 3.2.12)
148
- activesupport (= 3.2.12)
160
+ rails (3.2.13)
161
+ actionmailer (= 3.2.13)
162
+ actionpack (= 3.2.13)
163
+ activerecord (= 3.2.13)
164
+ activeresource (= 3.2.13)
165
+ activesupport (= 3.2.13)
149
166
  bundler (~> 1.0)
150
- railties (= 3.2.12)
167
+ railties (= 3.2.13)
151
168
  rails_autolink (1.0.9)
152
169
  rails (~> 3.1)
153
- railties (3.2.12)
154
- actionpack (= 3.2.12)
155
- activesupport (= 3.2.12)
170
+ railties (3.2.13)
171
+ actionpack (= 3.2.13)
172
+ activesupport (= 3.2.13)
156
173
  rack-ssl (~> 1.3.2)
157
174
  rake (>= 0.8.7)
158
175
  rdoc (~> 3.4)
159
176
  thor (>= 0.14.6, < 2.0)
160
177
  rake (10.0.3)
161
- rdoc (3.12.1)
178
+ rdoc (3.12.2)
162
179
  json (~> 1.4)
163
180
  rest-client (1.6.7)
164
181
  mime-types (>= 1.16)
@@ -190,16 +207,17 @@ GEM
190
207
  therubyracer (0.10.2)
191
208
  libv8 (~> 3.3.10)
192
209
  thor (0.17.0)
193
- tilt (1.3.3)
210
+ tilt (1.3.6)
194
211
  treetop (1.4.12)
195
212
  polyglot
196
213
  polyglot (>= 0.3.1)
197
214
  turn (0.9.6)
198
215
  ansi
199
- tzinfo (0.3.35)
216
+ tzinfo (0.3.37)
200
217
  uglifier (1.3.0)
201
218
  execjs (>= 0.3.0)
202
219
  multi_json (~> 1.0, >= 1.0.2)
220
+ unicode-display_width (0.1.1)
203
221
  view_marker (1.0.0)
204
222
  rails
205
223
  webmock (1.8.11)
@@ -216,19 +234,19 @@ PLATFORMS
216
234
  DEPENDENCIES
217
235
  activerecord-jdbcmysql-adapter
218
236
  activerecord-jdbcsqlite3-adapter
219
- activerecord-oracle_enhanced-adapter
220
237
  authlogic
221
238
  awesome_print
222
239
  better_errors
223
240
  binding_of_caller
224
241
  cancan
242
+ cane
225
243
  capybara
226
244
  capybara-screenshot
227
245
  capybara-webkit (~> 0.14.2)
228
246
  database_cleaner
229
247
  factory_girl_rails
230
- fastercsv
231
248
  heroku
249
+ hirb-unicode
232
250
  iq_rdf
233
251
  iq_triplestorage
234
252
  jruby-openssl
@@ -239,8 +257,10 @@ DEPENDENCIES
239
257
  nokogiri (~> 1.5.0)
240
258
  pg
241
259
  pry
260
+ pry-debugger
261
+ pry-rails
242
262
  pry-remote
243
- rails (= 3.2.12)
263
+ rails (= 3.2.13)
244
264
  rails_autolink
245
265
  sass-rails (~> 3.2.5)
246
266
  simple_form
data/README.md CHANGED
@@ -31,11 +31,11 @@ To run iQvoc on heroku do the following:
31
31
 
32
32
  ```
33
33
  bundle install
34
- bundle exec heroku create --stack bamboo
34
+ bundle exec heroku create
35
35
  bundle exec rake heroku:config
36
36
  git push heroku master
37
- bundle exec heroku rake db:migrate
38
- bundle exec heroku rake db:seed
37
+ bundle exec heroku run rake db:migrate
38
+ bundle exec heroku run rake db:seed
39
39
  bundle exec heroku restart
40
40
  ```
41
41
 
@@ -43,10 +43,6 @@ bundle exec heroku restart
43
43
 
44
44
  Remember to visit the Users section and change the default passwords!
45
45
 
46
- **Remarks:**
47
- For now iQvoc only supports the standard Bamboo stack. Cedar is not supported as we have `sqlite3` as a dependency
48
- in the Gemfile and Cedar does not support a custom `BUNDLE_WITHOUT` config like Bamboo at the moment.
49
-
50
46
  ### Custom
51
47
 
52
48
  We recommend running [iQvoc as a Rails engine](https://github.com/innoq/iqvoc/wiki/iQvoc-as-a-Rails-Engine).
@@ -19,11 +19,8 @@ class Concepts::HierarchicalController < ConceptsController
19
19
  def index
20
20
  authorize! :read, Iqvoc::Concept.base_class
21
21
 
22
- scope = if params[:published] == '0'
23
- Iqvoc::Concept.base_class.editor_selectable
24
- else
25
- Iqvoc::Concept.base_class.published
26
- end
22
+ scope = Iqvoc::Concept.base_class
23
+ scope = params[:published] == "0" ? scope.editor_selectable : scope.published
27
24
 
28
25
  #collect only the not expired concepts
29
26
  scope = scope.not_expired
@@ -0,0 +1,51 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2011 innoQ Deutschland GmbH
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ class Concepts::SchemeController < ApplicationController
18
+
19
+ def show
20
+ @scheme = Iqvoc::Concept.root_class.instance
21
+ authorize! :read, @scheme
22
+
23
+ @top_concepts = Iqvoc::Concept.base_class.tops.published
24
+
25
+ respond_to do |format|
26
+ format.html do
27
+ end
28
+ format.any :rdf, :ttl do
29
+ end
30
+ end
31
+ end
32
+
33
+ def edit
34
+ @scheme = Iqvoc::Concept.root_class.instance
35
+ authorize! :update, @scheme
36
+ end
37
+
38
+ def update
39
+ @scheme = Iqvoc::Concept.root_class.instance
40
+ authorize! :update, @scheme
41
+
42
+ if @scheme.update_attributes(params[:concept])
43
+ flash[:success] = t("txt.controllers.concept_scheme.save.success")
44
+ redirect_to scheme_path
45
+ else
46
+ flash[:error] = t("txt.controllers.concept_scheme.save.error")
47
+ render :edit
48
+ end
49
+ end
50
+
51
+ end
@@ -97,6 +97,8 @@ class ConceptsController < ApplicationController
97
97
  Iqvoc::Concept.note_class_names.each do |note_class_name|
98
98
  @concept.send(note_class_name.to_relation_name).build if @concept.send(note_class_name.to_relation_name).empty?
99
99
  end
100
+
101
+ @concept.notations.build if @concept.notations.none?
100
102
  end
101
103
 
102
104
  def create
@@ -0,0 +1,105 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2011 innoQ Deutschland GmbH
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ class HierarchyController < ApplicationController
18
+
19
+ def show
20
+ authorize! :read, Iqvoc::Concept.base_class
21
+
22
+ root_origin = params[:root]
23
+ direction = params[:dir] == "up" ? "up" : "down"
24
+ depth = params[:depth].blank? ? 3 : (Float(params[:depth]).to_i rescue nil)
25
+ include_siblings = params[:siblings] || false
26
+ include_unpublished = params[:published] == "0" # FIXME: requires additional AuthZ check
27
+
28
+ scope = Iqvoc::Concept.base_class
29
+ scope = include_unpublished ? scope.editor_selectable : scope.published
30
+
31
+ # validate depth parameter
32
+ error = "invalid depth parameter" unless depth # TODO: i18n
33
+ # validate root parameter
34
+ error = "missing root parameter" unless root_origin # TODO: i18n
35
+ unless error
36
+ root_concept = scope.where(:origin => root_origin).first
37
+ error = [404, "no concept matching root parameter"] unless root_concept # TODO: i18n
38
+ end
39
+ # error handling
40
+ if error
41
+ status, error = error if error.is_a? Array
42
+ flash.now[:error] = error
43
+ render :status => (status || 400)
44
+ return
45
+ end
46
+
47
+ # caching -- NB: invalidated on any in-scope concept modifications
48
+ latest = scope.maximum(:updated_at)
49
+ response.cache_control[:public] = !include_unpublished # XXX: this should not be necessary!?
50
+ return unless stale?(:etag => [latest, params], :last_modified => latest,
51
+ :public => !include_unpublished)
52
+
53
+ # NB: order matters due to the `where` clause below
54
+ if direction == "up"
55
+ scope = scope.includes(:narrower_relations, :broader_relations)
56
+ else
57
+ scope = scope.includes(:broader_relations, :narrower_relations)
58
+ end
59
+
60
+ @concepts = {}
61
+ if include_siblings
62
+ determine_siblings(root_concept).each { |sib| @concepts[sib] = {} }
63
+ end
64
+ @concepts[root_concept] = populate_hierarchy(root_concept, scope, depth, 0,
65
+ include_siblings)
66
+
67
+ @relation_class = Iqvoc::Concept.broader_relation_class
68
+ @relation_class = @relation_class.narrower_class unless direction == "up"
69
+
70
+ respond_to do |format|
71
+ format.html
72
+ format.ttl
73
+ format.rdf
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ # returns a hash of concept/relations pairs of arbitrary nesting depth
80
+ # NB: recursive, triggering one database query per iteration
81
+ def populate_hierarchy(root_concept, scope, max_depth, current_depth=0,
82
+ include_siblings=false)
83
+ current_depth += 1
84
+ return {} if current_depth > max_depth
85
+
86
+ rels = scope.where(Concept::Relation::Base.arel_table[:target_id].
87
+ eq(root_concept.id))
88
+ return rels.inject({}) do |memo, concept|
89
+ if include_siblings
90
+ determine_siblings(concept).each { |sib| memo[sib] = {} }
91
+ end
92
+ memo[concept] = populate_hierarchy(concept, scope, max_depth,
93
+ current_depth, include_siblings)
94
+ memo
95
+ end
96
+ end
97
+
98
+ # NB: includes support for poly-hierarchies -- XXX: untested
99
+ def determine_siblings(concept)
100
+ return concept.broader_relations.map do |rel|
101
+ rel.target.narrower_relations.map { |rel| rel.target } # XXX: expensive
102
+ end.flatten.uniq
103
+ end
104
+
105
+ end
@@ -17,16 +17,6 @@
17
17
  class RdfController < ApplicationController
18
18
  skip_before_filter :set_locale
19
19
 
20
- def scheme
21
- respond_to do |format|
22
- format.html { redirect_to about_path }
23
- format.any do
24
- authorize! :read, Iqvoc::Concept.root_class.instance
25
- @top_concepts = Iqvoc::Concept.base_class.tops.published.all
26
- end
27
- end
28
- end
29
-
30
20
  def show
31
21
  scope = if params[:published] == "0"
32
22
  Iqvoc::Concept.base_class.unpublished
@@ -31,7 +31,11 @@ class UserSessionsController < ApplicationController
31
31
  if @user_session.save
32
32
  @current_ability = nil
33
33
  flash[:success] = I18n.t("txt.controllers.user_sessions.login_success")
34
- redirect_to params[:back_to].presence || (can?(:use, :dashboard) ? dashboard_path : root_path)
34
+ if params[:back_to]
35
+ redirect_to URI.parse(params[:back_to]).path
36
+ else
37
+ redirect_to can?(:use, :dashboard) ? dashboard_path : root_path
38
+ end
35
39
  else
36
40
  flash[:error] = I18n.t("txt.views.user_sessions.error")
37
41
  render :action => :new
@@ -37,7 +37,7 @@ module ApplicationHelper
37
37
  details
38
38
  end
39
39
 
40
- # Formats a list ob items or returns a remark if no items where given
40
+ # Formats a list of items or returns a remark if no items where given
41
41
  def item_listing(items, &block)
42
42
  return nil if items.empty?
43
43
 
@@ -22,6 +22,21 @@ module ConceptsHelper
22
22
  :locals => { :concepts => concepts, :broader => broader }
23
23
  end
24
24
 
25
+ # turns a hash of concept/relations pairs of arbitrary nesting depth into the
26
+ # corresponding HTML list
27
+ def nested_list(hash, options={})
28
+ ordered = options[:ordered] || false
29
+ options.delete(:ordered)
30
+
31
+ content_tag(ordered ? "ol" : "ul", options) do
32
+ hash.map do |concept, rels|
33
+ rels.empty? ? content_tag("li", concept) : content_tag("li") do
34
+ h(concept) + nested_list(rels, :ordered => ordered) # NB: recursive
35
+ end
36
+ end.join("\n").html_safe
37
+ end
38
+ end
39
+
25
40
  def letter_selector(&block)
26
41
  letters = ('A'..'Z').to_a +
27
42
  (0..9).to_a +
@@ -60,6 +75,10 @@ module ConceptsHelper
60
75
  render_concept_association(res, concept, note_class)
61
76
  end
62
77
 
78
+ Iqvoc::Concept.notation_classes.each do |notation_class|
79
+ render_concept_association(res, concept, notation_class)
80
+ end
81
+
63
82
  Iqvoc::Concept.additional_association_classes.keys.each do |assoc_class|
64
83
  render_concept_association(res, concept, assoc_class)
65
84
  end
@@ -37,6 +37,7 @@ module RdfHelper
37
37
  c.Owl::deprecated(true) if concept.expired_at and concept.expired_at <= Date.new
38
38
 
39
39
  c.Skos::topConceptOf IqRdf.build_uri(Iqvoc::Concept.root_class.instance.origin) if concept.top_term?
40
+ c.Skos::inScheme IqRdf.build_uri(Iqvoc::Concept.root_class.instance.origin)
40
41
 
41
42
  concept.labelings.each do |labeling|
42
43
  labeling.build_rdf(document, c)
@@ -54,6 +55,10 @@ module RdfHelper
54
55
  match.build_rdf(document, c)
55
56
  end
56
57
 
58
+ concept.notations.each do |notation|
59
+ notation.build_rdf(document, c)
60
+ end
61
+
57
62
  Iqvoc::Concept.additional_association_class_names.keys.each do |class_name|
58
63
  concept.send(class_name.to_relation_name).each do |additional_object|
59
64
  additional_object.build_rdf(document, c)
@@ -132,6 +132,10 @@ class Concept::Base < ActiveRecord::Base
132
132
  has_many :collections, :through => :collection_members, :class_name => Iqvoc::Collection.base_class_name
133
133
  include_to_deep_cloning(:collection_members)
134
134
 
135
+ has_many :notations, :class_name => 'Notation::Base', :foreign_key => 'concept_id', :dependent => :destroy
136
+ include_to_deep_cloning :notations
137
+ @nested_relations << :notations
138
+
135
139
  # ************** "Dynamic"/configureable relations
136
140
 
137
141
  # *** Concept2Concept relations
@@ -256,7 +260,7 @@ class Concept::Base < ActiveRecord::Base
256
260
 
257
261
  def self.with_associations
258
262
  includes([
259
- { :labelings => :target }, :relations, :matches, :notes
263
+ { :labelings => :target }, :relations, :matches, :notes, :notations
260
264
  ])
261
265
  end
262
266
 
@@ -375,6 +379,11 @@ class Concept::Base < ActiveRecord::Base
375
379
  notes.select{ |note| note.class.name == note_class }
376
380
  end
377
381
 
382
+ def notations_for_class(notation_class)
383
+ notation_class = notation_class.name if notation_class < ActiveRecord::Base # Use the class name string
384
+ notations.select{ |notation| notation.class.name == notation_class }
385
+ end
386
+
378
387
  # This shows up (in brackets) to the right of a concept link if it doesn't
379
388
  # return nil
380
389
  def additional_info
@@ -25,7 +25,7 @@ class Concept::Relation::SKOS::Base < Concept::Relation::Base
25
25
  relation_class = Iqvoc::RDFAPI::PREDICATE_DICTIONARY[rdf_predicate] || self
26
26
 
27
27
  relation_instance = rdf_subject.send(self.name.to_relation_name).select{|rel| rel.target == rdf_object}
28
- unless relation_instance
28
+ if relation_instance.empty?
29
29
  relation_instance = relation_class.new(:target => rdf_object)
30
30
  rdf_subject.send(self.name.to_relation_name) << relation_instance
31
31
  end
@@ -42,6 +42,13 @@ class Concept::Relation::SKOS::Base < Concept::Relation::Base
42
42
 
43
43
  def build_rdf(document, subject)
44
44
  subject.send(self.rdf_namespace.camelcase).send(self.rdf_predicate, IqRdf.build_uri(target.origin))
45
+
46
+ # Auto-include preferred labels for referenced concepts
47
+ document << IqRdf::build_uri(target.origin) do |subject|
48
+ target.pref_labelings.each do |labeling|
49
+ subject.skos.send(labeling.rdf_predicate, labeling.target.value.to_s, :lang => labeling.target.language)
50
+ end
51
+ end
45
52
  end
46
53
 
47
54
  end