mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 09:42:07 +08:00
DEV: Allow using an AR relation as a model in services
This patch allows using an AR relation as a model in services without fetching associated records. It will just check if the relation is empty or not. In the former case, the execution will stop at that point, as expected.
This commit is contained in:
parent
db6eff7be9
commit
0636855706
|
@ -139,13 +139,15 @@ module Service
|
|||
|
||||
def call(instance, context)
|
||||
context[name] = super
|
||||
raise ArgumentError, "Model not found" if !optional && context[name].blank?
|
||||
if !optional && (!context[name] || context[name].try(:empty?))
|
||||
raise ArgumentError, "Model not found"
|
||||
end
|
||||
if context[name].try(:invalid?)
|
||||
context[result_key].fail(invalid: true)
|
||||
context.fail!
|
||||
end
|
||||
rescue ArgumentError => exception
|
||||
context[result_key].fail(exception: exception)
|
||||
context[result_key].fail(exception: exception, not_found: true)
|
||||
context.fail!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -80,7 +80,9 @@ class ServiceRunner
|
|||
default_name: "default",
|
||||
},
|
||||
on_model_not_found: {
|
||||
condition: ->(name = "model") { failure_for?("result.model.#{name}") && result[name].blank? },
|
||||
condition: ->(name = "model") do
|
||||
failure_for?("result.model.#{name}") && result["result.model.#{name}"].not_found
|
||||
end,
|
||||
key: %w[result model],
|
||||
default_name: "model",
|
||||
},
|
||||
|
|
|
@ -136,6 +136,18 @@ RSpec.describe ServiceRunner do
|
|||
end
|
||||
end
|
||||
|
||||
class RelationModelService
|
||||
include Service::Base
|
||||
|
||||
model :fake_model
|
||||
|
||||
private
|
||||
|
||||
def fetch_fake_model
|
||||
User.where(admin: false)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".call(service, &block)" do
|
||||
subject(:runner) { described_class.call(service, object, &actions_block) }
|
||||
|
||||
|
@ -145,7 +157,9 @@ RSpec.describe ServiceRunner do
|
|||
let(:actions) { "proc {}" }
|
||||
let(:object) do
|
||||
Class
|
||||
.new(Chat::ApiController) do
|
||||
.new(ApplicationController) do
|
||||
include WithServiceHelper
|
||||
|
||||
def request
|
||||
OpenStruct.new
|
||||
end
|
||||
|
@ -352,6 +366,34 @@ RSpec.describe ServiceRunner do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when fetching an ActiveRecord relation" do
|
||||
let(:service) { RelationModelService }
|
||||
|
||||
context "when the service does not fail" do
|
||||
before { Fabricate(:user) }
|
||||
|
||||
it "does not run the provided block" do
|
||||
expect(runner).not_to eq :no_model
|
||||
end
|
||||
|
||||
it "does not fetch records from the relation" do
|
||||
runner
|
||||
expect(result[:fake_model]).not_to be_loaded
|
||||
end
|
||||
end
|
||||
|
||||
context "when the service fails" do
|
||||
it "runs the provided block" do
|
||||
expect(runner).to eq :no_model
|
||||
end
|
||||
|
||||
it "does not fetch records from the relation" do
|
||||
runner
|
||||
expect(result[:fake_model]).not_to be_loaded
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when using the on_model_errors action" do
|
Loading…
Reference in New Issue
Block a user