Created
February 15, 2019 18:49
-
-
Save delbetu/26dc4b7d952669ee6ea7cdc87e9facfd to your computer and use it in GitHub Desktop.
These gists show a refactor which objective is isolate code that is part of a controller.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class IsolatedCode | |
| def initialize(release_being_sent = { state: 'published' }, | |
| release) | |
| @release_being_sent = release_being_sent | |
| @release = release | |
| end | |
| def foo | |
| ActiveRecord::Base.transaction do | |
| if publishing? | |
| namespace.lock!('FOR UPDATE NOWAIT') | |
| if publishable? | |
| release.update!(release_update_params) | |
| Release::Publication::ProcessAfterActions.call(release: release) | |
| else | |
| return 'not_publishable' | |
| end | |
| else | |
| release.update!(release_update_params) | |
| end | |
| end | |
| end | |
| private | |
| def publishing? | |
| if release_being_sent.present? && release_being_sent[:state] == 'published' && | |
| !release.published? | |
| return true | |
| end | |
| false | |
| end | |
| def publishable?(release) | |
| validation = Release::Publication::Validate.call(release: release) | |
| # Raise an exception if the context failed while evaluating release errors | |
| # Don't confuse this (unlikely) processing error handling with the errors/warnings related to the release | |
| fail "Publication validation exception: #{validation.message}" if validation.failure? | |
| validation.errors.blank? | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def update | |
| o = IsolatedCode.new(params[:release], release: release, namespace: namespace) | |
| if o.foo == 'not_publishable' | |
| render(status: :bad_request, body: I18n.t('release_validation.errors_present')) && return | |
| end | |
| render status: :no_content | |
| end | |
| def namespace | |
| @namespace ||= Th::Namespace.includes(:releases).find_by!(api_name: params[:namespace_api_name]) | |
| end | |
| def releases | |
| @releases ||= namespace.releases | |
| end | |
| def release | |
| @release ||= releases.find_by!(api_name: params[:api_name]) | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class IsolatedCode | |
| def initialize(release_being_sent = { state: 'published' }, | |
| release) | |
| @release_being_sent = release_being_sent | |
| @release = release | |
| end | |
| def foo | |
| ActiveRecord::Base.transaction do | |
| if publishing? | |
| namespace.lock!('FOR UPDATE NOWAIT') | |
| if publishable? | |
| release.update!(release_update_params) | |
| Release::Publication::ProcessAfterActions.call(release: release) | |
| else | |
| return 'not_publishable' | |
| end | |
| else | |
| release.update!(release_update_params) | |
| end | |
| end | |
| end | |
| private | |
| def publishing? | |
| if release_being_sent.present? && release_being_sent[:state] == 'published' && | |
| !release.published? | |
| return true | |
| end | |
| false | |
| end | |
| def publishable?(release) | |
| validation = Release::Publication::Validate.call(release: release) | |
| # Raise an exception if the context failed while evaluating release errors | |
| # Don't confuse this (unlikely) processing error handling with the errors/warnings related to the release | |
| fail "Publication validation exception: #{validation.message}" if validation.failure? | |
| validation.errors.blank? | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class IsolatedCode | |
| def initialize(release_being_sent = { state: 'published' }, | |
| release, transaction_manager: ActiveRecord::Base, | |
| release_publication: Release::Publication::ProcessAfterActions, | |
| release_validator: Release::Publication::Validate | |
| ) | |
| @release_being_sent = release_being_sent | |
| @release = release | |
| end | |
| def foo | |
| transaction_manager.transaction do | |
| if publishing? | |
| namespace.lock!('FOR UPDATE NOWAIT') | |
| if publishable? | |
| release.update!(release_update_params) | |
| release_publication.call(release: release) | |
| else | |
| return 'not_publishable' | |
| end | |
| else | |
| release.update!(release_update_params) | |
| end | |
| end | |
| end | |
| private | |
| def publishing? | |
| if release_being_sent.present? && release_being_sent[:state] == 'published' && | |
| !release.published? | |
| return true | |
| end | |
| false | |
| end | |
| def publishable?(release) | |
| validation = release_validator.call(release: release) | |
| # Raise an exception if the context failed while evaluating release errors | |
| # Don't confuse this (unlikely) processing error handling with the errors/warnings related to the release | |
| fail "Publication validation exception: #{validation.message}" if validation.failure? | |
| validation.errors.blank? | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
initial_solutionshows a controller action which depends on active record.second_solutionintroduces a collaborator. It helps to split responsibilities. Controller only does controller stuff (manage request and render the page). Since Controller doesn't do much you can avoid testing it and test the collaborator.third_solutionIdentifies the active_record (and others) dependencies on IsolatedCode and parameterize them.After this refactor you can test IsolatedCode#foo instead of testing the controller#update.
All dependencies are parameterized so the test can pass fake objects for these dependencies.