Module: Trailblazer::Macro::Contract
- Defined in:
- lib/trailblazer/macro/contract.rb,
lib/trailblazer/macro/contract/build.rb,
lib/trailblazer/macro/contract/persist.rb,
lib/trailblazer/macro/contract/validate.rb
Defined Under Namespace
Modules: DSL Classes: Validate
Class Method Summary collapse
- .Build(name: "default", constant: nil, builder: nil) ⇒ Object
- .Persist(method: :save, name: "default") ⇒ Object
-
.Validate(skip_extract: false, name: "default", representer: false, key: nil, constant: nil, invalid_data_terminus: false) ⇒ Object
result.contract = .. result.contract.errors = .. Deviate to left track if optional key is not found in params.
Class Method Details
.Build(name: "default", constant: nil, builder: nil) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/trailblazer/macro/contract/build.rb', line 6 def self.Build(name: "default", constant: nil, builder: nil) contract_path = :"contract.#{name}" injections = { Activity::Railway.Inject("#{contract_path}.class") => ->(*) { constant }, # default to {constant} if not injected. } # DISCUSS: can we force-default this via Inject()? input = { Activity::Railway.In() => ->(ctx, **) do ctx.to_hash.merge( constant: constant, name: contract_path ) end } output = { Activity::Railway.Out() => [contract_path] } default_contract_builder = ->(ctx, model: nil, **) { ctx[:"#{contract_path}.class"].new(model) } # proc is called via {Option()}. task_option_proc = builder || default_contract_builder # after the builder proc is run, assign its result to {:"contract.default"}. task = Macro.task_adapter_for_decider(task_option_proc, variable_name: contract_path) { task: task, id: "contract.build", } .merge(injections) .merge(input) .merge(output) end |
.Persist(method: :save, name: "default") ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 |
# File 'lib/trailblazer/macro/contract/persist.rb', line 4 def self.Persist(method: :save, name: "default") path = :"contract.#{name}" step = ->(ctx, **) { ctx[path].send(method) } task = Activity::Circuit::TaskAdapter.for_step(step) { task: task, id: "persist.save" } end |
.Validate(skip_extract: false, name: "default", representer: false, key: nil, constant: nil, invalid_data_terminus: false) ⇒ Object
result.contract = .. result.contract.errors = .. Deviate to left track if optional key is not found in params. Deviate to left if validation result falsey.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/trailblazer/macro/contract/validate.rb', line 8 def self.Validate(skip_extract: false, name: "default", representer: false, key: nil, constant: nil, invalid_data_terminus: false) # DISCUSS: should we introduce something like Validate::Deserializer? contract_path = :"contract.#{name}" # the contract instance params_path = :"contract.#{name}.params" # extract_params! save extracted params here. key_path = :"contract.#{name}.extract_key" extract = Validate::Extract.new(key_path: key_path, params_path: params_path) validate = Validate.new(name: name, representer: representer, params_path: params_path, contract_path: contract_path) # These are defaulting dependency injection, more here # https://trailblazer.to/2.1/docs/activity.html#activity-dependency-injection-inject-defaulting # Build a simple Railway {Activity} for the internal flow. activity = Activity::Railway(name: "Contract::Validate") do unless skip_extract step extract, id: "#{params_path}_extract", Output(:failure) => End(:extract_failure), Inject(key_path) => ->(*) { key } # default to {key} if not injected. end step validate, id: "contract.#{name}.call", Inject(contract_path) => ->(*) { constant } # default the contract instance to {constant}, if not injected (or passed down from {Build()}) end = activity.Subprocess(activity) .merge!(id: "contract.#{name}.validate") # Deviate End.extract_failure to the standard failure track as a default. This can be changed from the user side. unless skip_extract .merge!(activity.Output(:extract_failure) => activity.Track(:failure)) end # Halt failure track to End with {contract.name.invalid}. if invalid_data_terminus .merge!(activity.Output(:failure) => activity.End(:invalid_data)) end end |