• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

archivesspace / archivesspace / 19916213389

04 Dec 2025 03:02AM UTC coverage: 80.708% (+1.4%) from 79.285%
19916213389

Pull #3803

github

661c5a
web-flow
Merge 418b25756 into 87083c526
Pull Request #3803: ANW-1831: Fix 404 console error for PUI resource `show` views

29005 of 35938 relevant lines covered (80.71%)

7935.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.36
/frontend/app/controllers/archival_objects_controller.rb
1
class ArchivalObjectsController < ApplicationController
11✔
2
  include ApplicationHelper
11✔
3

4
  set_access_control  "view_repository" => [:index, :show, :models_in_graph],
11✔
5
                      "update_resource_record" => [:new, :edit, :create, :update, :transfer, :rde, :add_children, :publish, :unpublish, :accept_children, :validate_rows],
6
                      "suppress_archival_record" => [:suppress, :unsuppress],
7
                      "delete_archival_record" => [:delete],
8
                      "manage_repository" => [:defaults, :update_defaults]
9

10
  def new
11✔
11
    if params[:duplicate_from_archival_object]
19✔
12
      new_find_opts = find_opts
4✔
13
      new_find_opts["resolve[]"].push("top_container::container_locations")
4✔
14

15
      archival_object_id = params[:duplicate_from_archival_object][:uri].split('/').pop
4✔
16

17
      @archival_object = JSONModel(:archival_object).find(archival_object_id, new_find_opts)
4✔
18
      @archival_object.ref_id = nil
4✔
19
      @archival_object.instances = []
4✔
20
      @archival_object.position = params[:position]
4✔
21

4✔
22
      flash[:success] = t("archival_object._frontend.messages.duplicated", archival_object_display_string: clean_mixed_content(@archival_object.display_string))
5✔
23
    else
5✔
24
      @archival_object = ArchivalObject.new._always_valid!
1✔
25
      @archival_object.parent = {'ref' => ArchivalObject.uri_for(params[:archival_object_id])} if params.has_key?(:archival_object_id)
1✔
26
      @archival_object.resource = {'ref' => Resource.uri_for(params[:resource_id])} if params.has_key?(:resource_id)
1✔
27
      @archival_object.position = params[:position]
5✔
28
      if defaults = user_defaults('archival_object')
1✔
29
        @archival_object.update(defaults.values)
14✔
30
      end
14✔
31

14✔
32
      if params[:accession_id]
15✔
33
        acc = Accession.find(params[:accession_id], find_opts)
14✔
34
        @archival_object.populate_from_accession(acc)
2✔
35

36
        flash.now[:info] = t("archival_object._frontend.messages.spawned", accession_display_string: clean_mixed_content(acc.title))
37
        flash[:spawned_from_accession] = acc.id
14✔
38
      end
5✔
39
    end
5✔
40

41
    return render_aspace_partial :partial => "archival_objects/new_inline" if inline?
6✔
42
  end
5✔
43

44
  def edit
3✔
45
    new_find_opts = find_opts
6✔
46
    new_find_opts["resolve[]"].push("top_container::container_locations")
24✔
47

48
    @archival_object = JSONModel(:archival_object).find(params[:id], new_find_opts)
6✔
49

8✔
50
    if @archival_object.suppressed
39✔
51
      return redirect_to(:action => :show, :id => params[:id], :inline => params[:inline])
33✔
52
    end
53

33✔
54
    render_aspace_partial :partial => "archival_objects/edit_inline" if inline?
6✔
55
  end
33✔
56

57

58
  def create
3✔
59
    handle_crud(:instance => :archival_object,
33✔
60
                :find_opts => find_opts,
61
                :on_invalid => ->() {
62
                  if inline?
63
                    render_aspace_partial :partial => "new_inline"
8✔
64
                  else
10✔
65
                    render action: :new
66
                  end
67
                },
2✔
68
                :on_valid => ->(id) {
2✔
69

70
                  resource = @archival_object['resource']['_resolved']
×
71
                  parent = @archival_object['parent'] ? @archival_object['parent']['_resolved'] : false
72

73
                  success_message = @archival_object.parent ?
74
                                      t("archival_object._frontend.messages.created_with_parent", archival_object_display_string: @archival_object.title, parent_display_string: parent['title'], resource_title: resource['title']) :
75
                                      t("archival_object._frontend.messages.created", archival_object_display_string: @archival_object.title, resource_title: resource['title'])
8✔
76
                  if params.has_key?(:plus_one)
8✔
77
                    flash[:success] = success_message
78
                  else
8✔
79
                    flash.now[:success] = success_message
80
                  end
81

8✔
82
                  if @archival_object["is_slug_auto"] == false &&
4✔
83
                     @archival_object["slug"] == nil &&
84
                     params["archival_object"] &&
4✔
85
                     params["archival_object"]["is_slug_auto"] == "1"
86

87
                    if params.has_key?(:plus_one)
8✔
88
                      flash[:warning] = t("slug.autogen_disabled")
89
                    else
90
                      flash.now[:warning] = t("slug.autogen_disabled")
91
                    end
92
                  end
93
                  if inline?
×
94
                    render_aspace_partial :partial => "archival_objects/edit_inline"
95
                  else
96
                    id = ArchivalObject.id_for(@archival_object.uri)
97
                    resource_id = Resource.id_for(@archival_object.resource['ref'])
98
                    redirect_to controller: :resources, action: :edit, id: resource_id, anchor: "tree::archival_object_#{id}"
8✔
99
                  end
7✔
100
                })
101
  end
1✔
102

1✔
103

1✔
104
  def update
3✔
105
    params['archival_object']['position'] = params['archival_object']['position'].to_i if params['archival_object']['position']
1✔
106

107
    @archival_object = JSONModel(:archival_object).find(params[:id], find_opts)
1✔
108
    resource = @archival_object['resource']['_resolved']
1✔
109
    parent = @archival_object['parent'] ? @archival_object['parent']['_resolved'] : false
9✔
110
    handle_crud(:instance => :archival_object,
14✔
111
                :obj => @archival_object,
112
                :on_invalid => ->() { return render_aspace_partial :partial => "edit_inline" },
13✔
113
                :on_valid => ->(id) {
13✔
114

13✔
115
                  flash_success = parent ?
14✔
116
                    t("archival_object._frontend.messages.updated_with_parent", archival_object_display_string: clean_mixed_content(@archival_object.title)) :
117
                    t("archival_object._frontend.messages.updated", archival_object_display_string: clean_mixed_content(@archival_object.title))
5✔
118
                  flash.now[:success] = flash_success
1✔
119
                  if @archival_object["is_slug_auto"] == false &&
1✔
120
                     @archival_object["slug"] == nil &&
8✔
121
                     params["archival_object"] &&
122
                     params["archival_object"]["is_slug_auto"] == "1"
123

8✔
124
                    flash.now[:warning] = t("slug.autogen_disabled")
8✔
125
                  end
126

127
                  render_aspace_partial :partial => "edit_inline"
1✔
128
                })
129
  end
130

131
  def current_record
3✔
132
    @archival_object
8✔
133
  end
134

135
  def show
3✔
136
    @resource_id = params['resource_id']
11✔
137

138
    new_find_opts = find_opts
3✔
139
    new_find_opts["resolve[]"].push("top_container::container_locations")
3✔
140

8✔
141
    @archival_object = JSONModel(:archival_object).find(params[:id], new_find_opts)
154✔
142

143
    flash.now[:info] = t("archival_object._frontend.messages.suppressed_info") if @archival_object.suppressed
154✔
144

151✔
145
    render_aspace_partial :partial => "archival_objects/show_inline" if inline?
3✔
146
  end
151✔
147

148

151✔
149
  def accept_children
3✔
150
    handle_accept_children(JSONModel(:archival_object))
151✔
151
  end
152

153

154
  def defaults
11✔
155
    defaults = DefaultValues.get 'archival_object'
×
156

157
    values = defaults ? defaults.form_values : {}
158

159
    @archival_object = JSONModel(:archival_object).new(values)._always_valid!
8✔
160

161
    @archival_object.display_string = t("default_values.form_title.archival_object")
162

163
    render "defaults"
164
  end
165

166

167
  def update_defaults
3✔
168
    begin
169
      DefaultValues.from_hash({
170
                                "record_type" => "archival_object",
171
                                "lock_version" => params[:archival_object].delete('lock_version'),
172
                                "defaults" => cleanup_params_for_schema(
8✔
173
                                                                        params[:archival_object],
174
                                                                        JSONModel(:archival_object).schema
175
                                                                        )
176
                              }).save
177

178
      flash[:success] = t("default_values.messages.defaults_updated")
179
      redirect_to :controller => :archival_objects, :action => :defaults
180
    rescue Exception => e
181
      flash[:error] = e.message
×
182
      redirect_to :controller => :archival_objects, :action => :defaults
183
    end
184
  end
185

186

187
  def transfer
3✔
188
    begin
189
      post_data = {
1✔
190
        :target_resource => params["transfer"]["ref"],
191
        :component => JSONModel(:archival_object).uri_for(params[:id])
192
      }
8✔
193

194
      response = JSONModel::HTTP.post_form("/repositories/#{session[:repo_id]}/component_transfers", post_data)
2✔
195

196
      if response.code == '200'
1✔
197
        @archival_object = JSONModel(:archival_object).find(params[:id], find_opts)
1✔
198
        resource = @archival_object['resource']['_resolved']
1✔
199
        flash[:success] = t("archival_object._frontend.messages.transfer_success", archival_object_display_string: clean_mixed_content(@archival_object.title), resource_title: clean_mixed_content(resource['title']))
2✔
200
        redirect_to :controller => :resources, :action => :edit, :id => JSONModel(:resource).id_for(params["transfer"]["ref"]), :anchor => "tree::archival_object_#{params[:id]}"
1✔
201
      else
1✔
202
        raise ASUtils.json_parse(response.body)['error'].to_s
1✔
203
      end
1✔
204

1✔
205
    rescue Exception => e
1✔
206
      flash[:error] = t("archival_object._frontend.messages.transfer_error", :exception => e)
207
      redirect_to :controller => :resources, :action => :edit, :id => params["transfer"]["current_resource_id"], :anchor => "tree::archival_object_#{params[:id]}"
×
208
    end
209
  end
210

211

212
  def delete
3✔
213
    archival_object = JSONModel(:archival_object).find(params[:id])
214

215
    previous_record = begin
216
      JSONModel::HTTP.get_json("#{archival_object['uri']}/previous")
217
    rescue RecordNotFound
8✔
218
      nil
1✔
219
    end
220
    begin
1✔
221
      archival_object.delete
1✔
222
    rescue ConflictException => e
223
      flash[:error] = t("archival_object._frontend.messages.delete_conflict", :error => t("errors.#{e.conflicts}", :default => e.message))
×
224
      resolver = Resolver.new(archival_object['uri'])
225
      return redirect_to resolver.view_uri
226
    end
1✔
227

228
    flash[:success] = t("archival_object._frontend.messages.deleted", archival_object_display_string: clean_mixed_content(archival_object.title))
×
229

230
    if previous_record
×
231
      redirect_to :controller => :resources, :action => :show, :id => JSONModel(:resource).id_for(archival_object['resource']['ref']), :anchor => "tree::archival_object_#{JSONModel(:archival_object).id_for(previous_record['uri'])}"
232
    else
233
      # no previous node, so redirect to the resource
1✔
234
      resolver = Resolver.new(archival_object['resource']['ref'])
235
      redirect_to resolver.view_uri
1✔
236
    end
1✔
237
  end
238

239

240
  def rde
3✔
241
    @parent = JSONModel(:archival_object).find(params[:id])
242
    @resource_uri = @parent['resource']['ref']
243
    @children = ArchivalObjectChildren.new
244
    @exceptions = []
245

8✔
246
    render_aspace_partial :partial => "shared/rde"
1✔
247
  end
1✔
248

1✔
249

1✔
250
  def add_children
3✔
251
    @parent = JSONModel(:archival_object).find(params[:id])
1✔
252
    @resource_uri = @parent['resource']['ref']
253

254
    if params[:archival_record_children].blank? or params[:archival_record_children]["children"].blank?
255

8✔
256
      @children = ArchivalObjectChildren.new
×
257
      flash.now[:error] = t("rde.messages.no_rows")
×
258

259
    else
260
      children_data = cleanup_params_for_schema(params[:archival_record_children], JSONModel(:archival_record_children).schema)
261

262
      begin
263
        @children = ArchivalObjectChildren.from_hash(children_data, false)
264

265
        if params["validate_only"] == "true"
×
266
          @exceptions = @children.children.collect {|c| JSONModel(:archival_object).from_hash(c, false)._exceptions}
267

268
          error_count = @exceptions.select {|e| !e.empty?}.length
×
269
          if error_count > 0
270
            flash.now[:error] = t("rde.messages.rows_with_errors", :count => error_count)
×
271
          else
272
            flash.now[:success] = t("rde.messages.rows_no_errors")
273
          end
274

275
          return render_aspace_partial :partial => "shared/rde"
×
276
        else
277
          @children.save(:archival_object_id => @parent.id)
×
278
        end
279

280
        return render :plain => t("rde.messages.success")
×
281
      rescue JSONModel::ValidationException => e
282
        @exceptions = @children.children.collect {|c| JSONModel(:archival_object).from_hash(c, false)._exceptions}
×
283

284
        if @exceptions.all?(&:blank?)
285
          e.errors.each { |key, vals| flash.now[:error] = "#{key} : #{vals.join('<br/>')}" }
×
286
        else
287
          flash.now[:error] = t("rde.messages.rows_with_errors", :count => @exceptions.select {|e| !e.empty?}.length)
×
288
        end
289
      end
290

291
    end
292

293
    render_aspace_partial :partial => "shared/rde"
294
  end
295

296

297
  def publish
3✔
298
    @archival_object = JSONModel(:archival_object).find(params[:id], find_opts)
×
299

300
    response = JSONModel::HTTP.post_form("#{@archival_object.uri}/publish")
301

302
    if response.code == '200'
8✔
303
      flash[:success] = t("archival_object._frontend.messages.published", archival_object_title: clean_mixed_content(@archival_object.title))
1✔
304
    else
305
      flash[:error] = ASUtils.json_parse(response.body)['error'].to_s
1✔
306
    end
307

1✔
308
    redirect_to "#{request.referer}#tree::archival_object_#{params[:id]}"
1✔
309
  end
310

311

312
  def unpublish
3✔
313
    @archival_object = JSONModel(:archival_object).find(params[:id], find_opts)
1✔
314

315
    response = JSONModel::HTTP.post_form("#{@archival_object.uri}/unpublish")
316

317
    if response.code == '200'
8✔
318
      flash[:success] = t("archival_object._frontend.messages.unpublished", archival_object_title: clean_mixed_content(@archival_object.title))
1✔
319
    else
320
      flash[:error] = ASUtils.json_parse(response.body)['error'].to_s
1✔
321
    end
322

1✔
323
    redirect_to "#{request.referer}#tree::archival_object_#{params[:id]}"
1✔
324
  end
325

326

327
  def validate_rows
3✔
328
    row_data = cleanup_params_for_schema(params[:archival_record_children], JSONModel(:archival_record_children).schema)
1✔
329

330
    # build the AOC record but don't bother validating it yet...
331
    aoc = ArchivalObjectChildren.from_hash(row_data, false, true)
332

8✔
333
    # validate each row individually (to avoid weird indexes in the error paths)
122✔
334
    render :json => aoc.children.collect {|c| JSONModel(:archival_object).from_hash(c, false)._exceptions}
335
  end
336

122✔
337

338
  def suppress
3✔
339
    archival_object = JSONModel(:archival_object).find(params[:id])
270✔
340
    archival_object.set_suppressed(true)
341

342
    flash[:success] = t("archival_object._frontend.messages.suppressed", archival_object_title: clean_mixed_content(archival_object.title))
343
    redirect_to(:controller => :resources, :action => :show, :id => JSONModel(:resource).id_for(archival_object['resource']['ref']), :anchor => "tree::archival_object_#{params[:id]}")
8✔
344
  end
345

346

347
  def unsuppress
3✔
348
    archival_object = JSONModel(:archival_object).find(params[:id])
×
349
    archival_object.set_suppressed(false)
350

351
    flash[:success] = t("archival_object._frontend.messages.unsuppressed", archival_object_title: clean_mixed_content(archival_object.title))
352
    redirect_to(:controller => :resources, :action => :show, :id => JSONModel(:resource).id_for(archival_object['resource']['ref']), :anchor => "tree::archival_object_#{params[:id]}")
8✔
353
  end
354

355

356
  def models_in_graph
3✔
357
    list_uri = JSONModel(:archival_object).uri_for(params[:id]) + "/models_in_graph"
×
358
    list = JSONModel::HTTP.get_json(list_uri)
359

360
    render :json => list.select { |type| type != "lang_material" }.map {|type|
361
      [type, t("#{type == 'archival_object' ? 'resource_component' : type}._singular")]
8✔
362
    }
363
  end
364
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc