plan_my_stuff 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bded03d75c7bd996c62c647b038a588a4286628e7f041e385d4464ea87955505
4
- data.tar.gz: 5b778d271d85a1ad5681d8617dec41875d5664d0c3ea861ab9421bef962de4d2
3
+ metadata.gz: 15988155f3d1798b5b0f43cbb1597f7e8b7ed881feb3db2504da7ecd74ab9c59
4
+ data.tar.gz: 35f298dce675a86ca15153a354411c23806e8420374fe5eb4fd7d2c392e0ed9d
5
5
  SHA512:
6
- metadata.gz: db446cfa7623c4091f67cecd89ab7dfe84207237e601fd53f4a73401fc02d2019072801c326d281febb54373817cb87d35c60e2929a2ec425f1aca3e7623ef49
7
- data.tar.gz: b7f4328f697271829202ee201f4c05a9e1553bc95d50b721cfc3132462c0401428b87e22bd79cdeb4962e249bea991b3f5d39cab9cb1a3c048ef13a647e31312
6
+ metadata.gz: 838ebf5cb77a3467fb291d76acd9b2ded4cc40d88e65673ca41374324736c6cdc11e5bbc0ed7e04eaf0c0bb5ac4f799c3052379cdc87edcd7343dc30be370059
7
+ data.tar.gz: b30d829c2255b61485c72d639992f1095f9726b7e6d8952114eef2e44c91f1016c0f05bd3abd238faf0be83a37c8b75ef492208351d33cbbe1f2f689270e7614
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.0
4
+
5
+ ### Added
6
+
7
+ - Every controller action now yields its primary object to a block when subclassed, so consumers can do
8
+ `super do |obj| ... end` to wedge in audit-log / instrumentation without rewriting the action. Webhook
9
+ controllers yield `(payload, result)`. See [CONFIGURATION.md](CONFIGURATION.md).
10
+
3
11
  ## 0.18.0
4
12
 
5
13
  ### Breaking
data/CONFIGURATION.md CHANGED
@@ -374,6 +374,54 @@ Controllable keys (with gem defaults):
374
374
  | `:'webhooks/github'` | `plan_my_stuff/webhooks/github` |
375
375
  | `:'webhooks/aws'` | `plan_my_stuff/webhooks/aws` |
376
376
 
377
+ ### Customizing per-action behavior
378
+
379
+ Every mounted route resolves its controller through `config.controller_for(key)`. Subclass a gem controller in your
380
+ own app and register it to wedge in `before_action`s, authentication, or response tweaks - no monkey patching:
381
+
382
+ ```ruby
383
+ # app/controllers/my_app/issues_controller.rb
384
+ class MyApp::IssuesController < PMS::IssuesController
385
+ before_action :authenticate_user!
386
+ before_action :authorize_ticket_access
387
+ end
388
+ ```
389
+
390
+ ```ruby
391
+ # config/initializers/plan_my_stuff.rb
392
+ PlanMyStuff.configure do |config|
393
+ config.controllers[:issues] = 'my_app/issues'
394
+ end
395
+ ```
396
+
397
+ For per-action side effects (audit log, metrics, notifications) without rewriting the action, yielding actions
398
+ pass their primary object to an optional block on the happy path. Call `super do |obj| ... end` from a subclass:
399
+
400
+ ```ruby
401
+ class MyApp::IssuesController < PMS::IssuesController
402
+ def create
403
+ super do |issue|
404
+ AuditLog.record(actor: current_user, action: :issue_created, target: issue)
405
+ end
406
+ end
407
+
408
+ def update
409
+ super do |issue|
410
+ AuditLog.record(actor: current_user, action: :issue_updated, target: issue)
411
+ end
412
+ end
413
+ end
414
+ ```
415
+
416
+ Contract:
417
+
418
+ - The yield fires on the happy path, after the model load / write succeeds and before the gem's default
419
+ `flash[:success]` + `redirect_to`. Error branches, `not_found`, and authorization redirects do not yield.
420
+ - Read actions (`index`, `show`, `new`, `edit`) yield before the implicit render; `index` yields the collection,
421
+ the rest yield the single object.
422
+ - If your block calls `render` or `redirect_to`, the gem's default response is skipped (the action checks
423
+ `performed?`), so you can fully replace the response from the block.
424
+
377
425
  ### Parent controller
378
426
 
379
427
  | Option | Type | Default | Description |
data/README.md CHANGED
@@ -787,34 +787,6 @@ All routes are under the engine's mount point. Each group can be disabled via `c
787
787
 
788
788
  ## Controller overrides
789
789
 
790
- Every mounted route resolves its controller through `config.controller_for(key)`, which looks up `config.controllers[key]` and falls back to the gem default. Subclass a gem controller in your own app and register it to wedge in before_actions, authentication, or response tweaks — no monkey patching.
791
-
792
- ```ruby
793
- # app/controllers/my_app/issues_controller.rb
794
- class MyApp::IssuesController < PMS::IssuesController
795
- before_action :authenticate_user!
796
- before_action :authorize_ticket_access
797
- end
798
- ```
799
-
800
- ```ruby
801
- # config/initializers/plan_my_stuff.rb
802
- PlanMyStuff.configure do |config|
803
- config.controllers['issues'] = 'my_app/issues'
804
- end
805
- ```
806
-
807
- Overridable keys (see `PMS::Configuration::DEFAULT_CONTROLLERS`):
808
-
809
- ```text
810
- issues issues/closures
811
- comments issues/viewers
812
- labels issues/takes
813
- projects issues/waitings
814
- project_items issues/links
815
- testing_projects issues/approvals
816
- testing_project_items project_items/statuses
817
- webhooks/github project_items/assignments
818
- webhooks/aws testing_project_items/results
819
- ```
790
+ See [CONFIGURATION.md](CONFIGURATION.md#controller-overrides) for the full walkthrough including subclassing,
791
+ per-route registration, and the per-action block hook.
820
792
 
@@ -6,7 +6,7 @@ module PlanMyStuff
6
6
  def create
7
7
  @issue = PlanMyStuff::Issue.find(params[:issue_id])
8
8
 
9
- PlanMyStuff::Comment.create!(
9
+ comment = PlanMyStuff::Comment.create!(
10
10
  issue: @issue,
11
11
  body: comment_params[:body],
12
12
  user: pms_current_user,
@@ -14,6 +14,9 @@ module PlanMyStuff
14
14
  waiting_on_reply: comment_params[:waiting_on_reply] == '1',
15
15
  )
16
16
 
17
+ yield(comment) if block_given?
18
+ return if performed?
19
+
17
20
  flash[:success] = 'Comment was successfully created.'
18
21
  redirect_to(plan_my_stuff.issue_path(@issue))
19
22
  rescue PlanMyStuff::LockedIssueError => e
@@ -27,9 +30,14 @@ module PlanMyStuff
27
30
  load_comment
28
31
  return unless @comment
29
32
  return redirect_to_issue if issue_body_comment?
30
- return if can_edit?(@comment)
31
33
 
32
- redirect_to_unauthorized(plan_my_stuff.issue_path(@issue))
34
+ unless can_edit?(@comment)
35
+ redirect_to_unauthorized(plan_my_stuff.issue_path(@issue))
36
+
37
+ return
38
+ end
39
+
40
+ yield(@comment) if block_given?
33
41
  end
34
42
 
35
43
  # PATCH/PUT /issues/:issue_id/comments/:id
@@ -49,6 +57,9 @@ module PlanMyStuff
49
57
 
50
58
  @comment.update!(**update_attrs, user: pms_current_user)
51
59
 
60
+ yield(@comment) if block_given?
61
+ return if performed?
62
+
52
63
  flash[:success] = 'Comment was successfully updated.'
53
64
  redirect_to(plan_my_stuff.issue_path(@issue))
54
65
  rescue PlanMyStuff::StaleObjectError => e
@@ -26,6 +26,9 @@ module PlanMyStuff
26
26
  issue = PlanMyStuff::Issue.find(params[:issue_id])
27
27
  issue.request_approvals!(user_ids: user_ids, user: pms_current_user)
28
28
 
29
+ yield(issue) if block_given?
30
+ return if performed?
31
+
29
32
  flash[:success] = 'Approvers were successfully added.'
30
33
  redirect_to(show_path)
31
34
  rescue PlanMyStuff::AuthorizationError, PlanMyStuff::ValidationError => e
@@ -71,6 +74,9 @@ module PlanMyStuff
71
74
  flash[:success] = 'Response revoked.'
72
75
  end
73
76
 
77
+ yield(issue) if block_given?
78
+ return if performed?
79
+
74
80
  redirect_to(show_path)
75
81
  rescue PlanMyStuff::AuthorizationError, PlanMyStuff::ValidationError => e
76
82
  pms_handle_rescue(e)
@@ -88,6 +94,9 @@ module PlanMyStuff
88
94
  issue = PlanMyStuff::Issue.find(params[:issue_id])
89
95
  issue.remove_approvers!(user_ids: [params[:id].to_i], user: pms_current_user)
90
96
 
97
+ yield(issue) if block_given?
98
+ return if performed?
99
+
91
100
  flash[:success] = 'Approver was successfully removed.'
92
101
  redirect_to(show_path)
93
102
  rescue PlanMyStuff::AuthorizationError, PlanMyStuff::ValidationError => e
@@ -14,6 +14,9 @@ module PlanMyStuff
14
14
  issue = PlanMyStuff::Issue.find(params[:issue_id])
15
15
  issue.update!(state: :closed)
16
16
 
17
+ yield(issue) if block_given?
18
+ return if performed?
19
+
17
20
  flash[:success] = 'Issue was successfully closed.'
18
21
  redirect_to(plan_my_stuff.issue_path(issue))
19
22
  rescue PlanMyStuff::Error, ArgumentError => e
@@ -27,6 +30,9 @@ module PlanMyStuff
27
30
  issue = PlanMyStuff::Issue.find(params[:issue_id])
28
31
  issue.update!(state: :open)
29
32
 
33
+ yield(issue) if block_given?
34
+ return if performed?
35
+
30
36
  flash[:success] = 'Issue was successfully reopened.'
31
37
  redirect_to(plan_my_stuff.issue_path(issue))
32
38
  rescue PlanMyStuff::Error, ArgumentError => e
@@ -28,6 +28,9 @@ module PlanMyStuff
28
28
  issue = PlanMyStuff::Issue.find(params[:issue_id])
29
29
  link = add_link(issue, type)
30
30
 
31
+ yield(issue) if block_given?
32
+ return if performed?
33
+
31
34
  flash[:success] = "Linked #{link}"
32
35
  redirect_to(plan_my_stuff.issue_path(issue))
33
36
  rescue PlanMyStuff::ValidationError, ActiveModel::ValidationError, ArgumentError => e
@@ -47,6 +50,9 @@ module PlanMyStuff
47
50
  issue = PlanMyStuff::Issue.find(params[:issue_id])
48
51
  remove_link(issue, type, repo: repo, number: number)
49
52
 
53
+ yield(issue) if block_given?
54
+ return if performed?
55
+
50
56
  flash[:success] = "Unlinked #{repo}##{number}"
51
57
  redirect_to(plan_my_stuff.issue_path(issue))
52
58
  rescue PlanMyStuff::ValidationError, ActiveModel::ValidationError, ArgumentError => e
@@ -19,6 +19,10 @@ module PlanMyStuff
19
19
 
20
20
  PlanMyStuff::Pipeline.take!(project_item)
21
21
  assign_current_user(project_item)
22
+
23
+ yield(project_item) if block_given?
24
+ return if performed?
25
+
22
26
  flash[:success] ||= "Issue ##{issue.number} taken."
23
27
 
24
28
  redirect_to(plan_my_stuff.issue_path(issue))
@@ -48,6 +52,10 @@ module PlanMyStuff
48
52
  issue.update!(assignees: remaining)
49
53
  end
50
54
 
55
+ yielded = project_item.presence || issue
56
+ yield(yielded) if block_given?
57
+ return if performed?
58
+
51
59
  flash[:success] = "Issue ##{issue.number} released."
52
60
  redirect_to(plan_my_stuff.issue_path(issue))
53
61
  rescue ArgumentError, PlanMyStuff::Error => e
@@ -26,6 +26,9 @@ module PlanMyStuff
26
26
  issue = PlanMyStuff::Issue.find(params[:issue_id])
27
27
  issue.add_viewers!(user_ids: viewer_ids, user: pms_current_user)
28
28
 
29
+ yield(issue) if block_given?
30
+ return if performed?
31
+
29
32
  flash[:success] = 'Viewers were successfully added.'
30
33
  redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]))
31
34
  rescue PlanMyStuff::Error, Octokit::Error => e
@@ -44,6 +47,9 @@ module PlanMyStuff
44
47
  issue = PlanMyStuff::Issue.find(params[:issue_id])
45
48
  issue.remove_viewers!(user_ids: [params[:id].to_i], user: pms_current_user)
46
49
 
50
+ yield(issue) if block_given?
51
+ return if performed?
52
+
47
53
  flash[:success] = 'Viewer was successfully removed.'
48
54
  redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]))
49
55
  rescue PlanMyStuff::Error, Octokit::Error => e
@@ -19,6 +19,9 @@ module PlanMyStuff
19
19
  issue = PlanMyStuff::Issue.find(params[:issue_id])
20
20
  issue.enter_waiting_on_user!(user: pms_current_user)
21
21
 
22
+ yield(issue) if block_given?
23
+ return if performed?
24
+
22
25
  flash[:success] = 'Issue marked as waiting on user reply.'
23
26
  redirect_to(plan_my_stuff.issue_path(issue))
24
27
  rescue PlanMyStuff::Error, ArgumentError => e
@@ -37,6 +40,9 @@ module PlanMyStuff
37
40
  issue = PlanMyStuff::Issue.find(params[:issue_id])
38
41
  issue.clear_waiting_on_user!
39
42
 
43
+ yield(issue) if block_given?
44
+ return if performed?
45
+
40
46
  flash[:success] = 'Waiting-on-user state cleared.'
41
47
  redirect_to(plan_my_stuff.issue_path(issue))
42
48
  rescue PlanMyStuff::Error, ArgumentError => e
@@ -17,11 +17,15 @@ module PlanMyStuff
17
17
  page: @page,
18
18
  per_page: @per_page,
19
19
  )
20
+
21
+ yield(@issues) if block_given?
20
22
  end
21
23
 
22
24
  # GET /issues/new
23
25
  def new
24
26
  @issue = PlanMyStuff::Issue.new
27
+
28
+ yield(@issue) if block_given?
25
29
  end
26
30
 
27
31
  # POST /issues
@@ -33,6 +37,9 @@ module PlanMyStuff
33
37
  user: pms_current_user,
34
38
  )
35
39
 
40
+ yield(@issue) if block_given?
41
+ return if performed?
42
+
36
43
  flash[:success] = 'Issue was successfully created.'
37
44
  redirect_to(plan_my_stuff.issue_path(@issue))
38
45
  rescue PlanMyStuff::ValidationError => e
@@ -50,11 +57,15 @@ module PlanMyStuff
50
57
  @current_user_login = PlanMyStuff.configuration.github_login_for[@current_user_id]
51
58
  @pipeline_enabled = PlanMyStuff.configuration.pipeline_enabled
52
59
  @pipeline_item = load_pipeline_item(@issue.number) if @pipeline_enabled
60
+
61
+ yield(@issue) if block_given?
53
62
  end
54
63
 
55
64
  # GET /issues/:id/edit
56
65
  def edit
57
66
  @issue = PlanMyStuff::Issue.find(params[:id])
67
+
68
+ yield(@issue) if block_given?
58
69
  end
59
70
 
60
71
  # PATCH/PUT /issues/:id
@@ -67,6 +78,9 @@ module PlanMyStuff
67
78
  labels: parse_labels(issue_params[:labels]),
68
79
  )
69
80
 
81
+ yield(@issue) if block_given?
82
+ return if performed?
83
+
70
84
  flash[:success] = 'Issue was successfully updated.'
71
85
  redirect_to(plan_my_stuff.issue_path(@issue))
72
86
  rescue PlanMyStuff::StaleObjectError => e
@@ -22,6 +22,9 @@ module PlanMyStuff
22
22
 
23
23
  PlanMyStuff::Label.add!(issue: issue, labels: labels)
24
24
 
25
+ yield(issue) if block_given?
26
+ return if performed?
27
+
25
28
  flash[:success] = 'Label was successfully added.'
26
29
  redirect_to(plan_my_stuff.issue_path(issue))
27
30
  rescue PlanMyStuff::Error, Octokit::Error => e
@@ -35,6 +38,9 @@ module PlanMyStuff
35
38
  issue = PlanMyStuff::Issue.find(params[:issue_id])
36
39
  PlanMyStuff::Label.remove!(issue: issue, labels: [params[:id]])
37
40
 
41
+ yield(issue) if block_given?
42
+ return if performed?
43
+
38
44
  flash[:success] = 'Label was successfully removed.'
39
45
  redirect_to(plan_my_stuff.issue_path(issue))
40
46
  rescue PlanMyStuff::Error, Octokit::Error => e
@@ -16,6 +16,9 @@ module PlanMyStuff
16
16
 
17
17
  item.assign!(assignees)
18
18
 
19
+ yield(item) if block_given?
20
+ return if performed?
21
+
19
22
  flash[:success] =
20
23
  if assignees.present?
21
24
  "Item assigned to #{assignees.join(', ')}."
@@ -43,6 +46,9 @@ module PlanMyStuff
43
46
 
44
47
  item.assign!(remaining)
45
48
 
49
+ yield(item) if block_given?
50
+ return if performed?
51
+
46
52
  flash[:success] = "#{params[:username]} unassigned."
47
53
  redirect_to(plan_my_stuff.project_path(params[:project_id]))
48
54
  rescue ArgumentError, PlanMyStuff::Error => e
@@ -14,6 +14,9 @@ module PlanMyStuff
14
14
 
15
15
  item.move_to!(params[:status])
16
16
 
17
+ yield(item) if block_given?
18
+ return if performed?
19
+
17
20
  flash[:success] = "Item moved to #{params[:status]}."
18
21
  redirect_to(plan_my_stuff.project_path(params[:project_id]))
19
22
  rescue ArgumentError, PlanMyStuff::Error => e
@@ -7,19 +7,23 @@ module PlanMyStuff
7
7
  project_number = params[:project_id].to_i
8
8
 
9
9
  if params[:draft] == '1'
10
- PlanMyStuff::ProjectItem.create!(
10
+ item = PlanMyStuff::ProjectItem.create!(
11
11
  params[:title],
12
12
  draft: true,
13
13
  body: params[:body],
14
14
  project_number: project_number,
15
15
  )
16
- flash[:success] = 'Draft item created.'
16
+ flash_message = 'Draft item created.'
17
17
  else
18
18
  issue = PlanMyStuff::Issue.find(params[:issue_number].to_i)
19
- PlanMyStuff::ProjectItem.create!(issue, project_number: project_number)
20
- flash[:success] = "Issue ##{issue.number} added to project."
19
+ item = PlanMyStuff::ProjectItem.create!(issue, project_number: project_number)
20
+ flash_message = "Issue ##{issue.number} added to project."
21
21
  end
22
22
 
23
+ yield(item) if block_given?
24
+ return if performed?
25
+
26
+ flash[:success] = flash_message
23
27
  redirect_to(plan_my_stuff.project_path(project_number))
24
28
  rescue ArgumentError, PlanMyStuff::Error, Octokit::Error => e
25
29
  pms_handle_rescue(e)
@@ -38,6 +42,9 @@ module PlanMyStuff
38
42
 
39
43
  item.destroy!(user: pms_current_user)
40
44
 
45
+ yield(item) if block_given?
46
+ return if performed?
47
+
41
48
  flash[:success] = 'Item removed from project.'
42
49
  redirect_to(plan_my_stuff.project_path(project_number))
43
50
  rescue ArgumentError, PlanMyStuff::Error, Octokit::Error => e
@@ -12,11 +12,15 @@ module PlanMyStuff
12
12
  when 'regular' then all_projects.reject { |p| p.is_a?(PlanMyStuff::TestingProject) }
13
13
  else all_projects
14
14
  end
15
+
16
+ yield(@projects) if block_given?
15
17
  end
16
18
 
17
19
  # GET /projects/new
18
20
  def new
19
21
  @project = PlanMyStuff::Project.new
22
+
23
+ yield(@project) if block_given?
20
24
  end
21
25
 
22
26
  # POST /projects
@@ -28,6 +32,9 @@ module PlanMyStuff
28
32
  user: pms_current_user,
29
33
  )
30
34
 
35
+ yield(@project) if block_given?
36
+ return if performed?
37
+
31
38
  flash[:success] = 'Project was successfully created.'
32
39
  redirect_to(plan_my_stuff.project_path(@project.number))
33
40
  rescue PlanMyStuff::ValidationError => e
@@ -46,11 +53,15 @@ module PlanMyStuff
46
53
  @project = PlanMyStuff::Project.find(params[:id].to_i)
47
54
  @statuses = @project.statuses.pluck(:name)
48
55
  @items_by_status = @project.items.group_by(&:status)
56
+
57
+ yield(@project) if block_given?
49
58
  end
50
59
 
51
60
  # GET /projects/:id/edit
52
61
  def edit
53
62
  @project = PlanMyStuff::Project.find(params[:id].to_i)
63
+
64
+ yield(@project) if block_given?
54
65
  end
55
66
 
56
67
  # PATCH/PUT /projects/:id
@@ -63,6 +74,9 @@ module PlanMyStuff
63
74
  description: project_params[:description],
64
75
  )
65
76
 
77
+ yield(@project) if block_given?
78
+ return if performed?
79
+
66
80
  flash[:success] = 'Project was successfully updated.'
67
81
  redirect_to(plan_my_stuff.project_path(@project.number))
68
82
  rescue PlanMyStuff::StaleObjectError => e
@@ -30,6 +30,9 @@ module PlanMyStuff
30
30
  raise(ArgumentError, "Invalid result: #{params[:result].inspect}")
31
31
  end
32
32
 
33
+ yield(item) if block_given?
34
+ return if performed?
35
+
33
36
  redirect_to(plan_my_stuff.testing_project_path(project_number))
34
37
  rescue PlanMyStuff::ValidationError => e
35
38
  pms_handle_rescue(e)
@@ -5,6 +5,8 @@ module PlanMyStuff
5
5
  # GET /testing_projects/:testing_project_id/items/new
6
6
  def new
7
7
  @project = PlanMyStuff::TestingProject.find(params[:testing_project_id].to_i)
8
+
9
+ yield(@project) if block_given?
8
10
  rescue PlanMyStuff::Error, Octokit::Error => e
9
11
  pms_handle_rescue(e)
10
12
  flash[:error] = e.message
@@ -26,6 +28,9 @@ module PlanMyStuff
26
28
  item.update_due_date!(Date.parse(item_params[:due_date])) if item_params[:due_date].present?
27
29
  item.update_pass_mode!(item_params[:pass_mode]) if item_params[:pass_mode].present?
28
30
 
31
+ yield(item) if block_given?
32
+ return if performed?
33
+
29
34
  flash[:success] = 'Item added.'
30
35
  redirect_to(plan_my_stuff.testing_project_path(project_number))
31
36
  rescue ArgumentError, PlanMyStuff::Error, Octokit::Error => e
@@ -6,6 +6,8 @@ module PlanMyStuff
6
6
  def new
7
7
  @project = PlanMyStuff::TestingProject.new
8
8
  @project.metadata.subject_urls = [params[:subject_url]] if params[:subject_url].present?
9
+
10
+ yield(@project) if block_given?
9
11
  end
10
12
 
11
13
  # POST /testing_projects
@@ -19,6 +21,9 @@ module PlanMyStuff
19
21
  user: pms_current_user,
20
22
  )
21
23
 
24
+ yield(@project) if block_given?
25
+ return if performed?
26
+
22
27
  flash[:success] = 'Testing project was successfully created.'
23
28
  redirect_to(plan_my_stuff.testing_project_path(@project.number))
24
29
  rescue PlanMyStuff::ValidationError => e
@@ -39,11 +44,15 @@ module PlanMyStuff
39
44
  @project = PlanMyStuff::TestingProject.find(params[:id].to_i)
40
45
  @statuses = @project.statuses.pluck(:name)
41
46
  @items_by_status = @project.items.group_by(&:status)
47
+
48
+ yield(@project) if block_given?
42
49
  end
43
50
 
44
51
  # GET /testing_projects/:id/edit
45
52
  def edit
46
53
  @project = PlanMyStuff::TestingProject.find(params[:id].to_i)
54
+
55
+ yield(@project) if block_given?
47
56
  end
48
57
 
49
58
  # PATCH/PUT /testing_projects/:id
@@ -60,6 +69,9 @@ module PlanMyStuff
60
69
  },
61
70
  )
62
71
 
72
+ yield(@project) if block_given?
73
+ return if performed?
74
+
63
75
  flash[:success] = 'Testing project was successfully updated.'
64
76
  redirect_to(plan_my_stuff.testing_project_path(@project.number))
65
77
  rescue PlanMyStuff::StaleObjectError => e
@@ -3,7 +3,7 @@
3
3
  module PlanMyStuff
4
4
  module VERSION
5
5
  MAJOR = 0
6
- MINOR = 18
6
+ MINOR = 19
7
7
  TINY = 0
8
8
 
9
9
  # Set PRE to nil unless it's a pre-release (beta, rc, etc.)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plan_my_stuff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brands Insurance
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-19 00:00:00.000000000 Z
11
+ date: 2026-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails