These are chat archives for dry-rb/chat

26th
Nov 2018
Jaromír Červenka
@Cervajz
Nov 26 2018 10:38
Hello :)
Is it possible to do somethinh like this please?
rule(parse_request_id: %i[parse_request_id]) do |parse_request_id|
  parse_request_id.filled? > parse_request_repository.find_by(id: value(parse_request_id)).filled?
end
I am trying to avoid this:
validate(exists?: :parse_request_id) do |parse_request_id|
  if parse_request.nil?
    true
  else
    parse_request_repository.find_by(id: parse_request_id).present?
  end
end
parse_request_id is optional and existence checked against DB if provided
Tim Riley
@timriley
Nov 26 2018 10:41
You can’t run arbitrary ruby code inside a rule block. What I think you want to do is make a cusastom predicate called parse_request_exists? which takes the ID and returns true/false if it exists
so then you have a line like this inside your rule block
Jaromír Červenka
@Cervajz
Nov 26 2018 10:41
Got it
I already have that
required(:customer_id).filled(:exists?)
Tim Riley
@timriley
Nov 26 2018 10:41
parse_request_id.filled? > parse_request_id.parse_request_exists?
Jaromír Červenka
@Cervajz
Nov 26 2018 10:41
def exists?(value)
record.class.where(id: value).exists?
end
Ok, so basically I'll create custom methods for every "model" i'd like to check
as I don't like the record.class.where -> it does not work for multiple checks in one schema
@timriley Thanks :)
Tim Riley
@timriley
Nov 26 2018 10:43
alternatively you could provide some way to identify the record as the second arg to the predicate method
Igor Alexandrov
@igor-alexandrov
Nov 26 2018 10:43
This message was deleted
Jaromír Červenka
@Cervajz
Nov 26 2018 10:43
I do it like this
Tim Riley
@timriley
Nov 26 2018 10:43
so it becomes something like:
request_id.filled? > request_id.record_exists?(:parse_request)
Jaromír Červenka
@Cervajz
Nov 26 2018 10:43
TargetRequest::CreateSchema.with(record: customer_repository.new).call(input).to_monad hints: false
Hmm
Tim Riley
@timriley
Nov 26 2018 10:43
And use the :parse_request name inside that predicate method to work out which repo to use or whatever
Jaromír Červenka
@Cervajz
Nov 26 2018 10:44
I see
Tim Riley
@timriley
Nov 26 2018 10:44
depends on how flexible you need to make this and how much you care (or not) about making multiple predicate methods
tbh I’d start by duplicating code and seeing how painful that really is in practice
Jaromír Červenka
@Cervajz
Nov 26 2018 10:44
Thinking about that
Having unique methods per record does not sound that bad - > it would be more explicit
Igor Alexandrov
@igor-alexandrov
Nov 26 2018 10:44
configure do 
  def exists?(klass, value)
    !!klass.find(value).empty?
  end
end

optional(: parse_request_id) {
  filled? > exists(ParseRequest)?
}
Jaromír Červenka
@Cervajz
Nov 26 2018 10:45
and if I change the model class I do it in one place
@igor-alexandrov Nice
Igor Alexandrov
@igor-alexandrov
Nov 26 2018 10:45
Solution above should also work
Thanks :)
Tim Riley
@timriley
Nov 26 2018 10:45
Yep :)
Jaromír Červenka
@Cervajz
Nov 26 2018 10:46
Thank you guys
Tim Riley
@timriley
Nov 26 2018 10:46
Go team
Igor Alexandrov
@igor-alexandrov
Nov 26 2018 10:47
Maybe somebody will take a look at my PR? dry-rb/dry-rb.org#267
Tim Riley
@timriley
Nov 26 2018 10:47
I’ll try take a look tomorrow morning
Igor Alexandrov
@igor-alexandrov
Nov 26 2018 10:48
great!
Jaromír Červenka
@Cervajz
Nov 26 2018 11:30
module TargetRequests
  CreateSchema = Dry::Validation.Schema(ApplicationSchema) do
    required(:customer_id).filled { valid_db_id? & record_exists?(Customer) }
    required(:parse_request_id).filled { valid_db_id? & record_exists?(ParseRequest) }

    optional(:webhook_id).filled { valid_db_id? & record_exists?(Webhook) }
    optional(:target_email_id).filled { valid_db_id? & record_exists?(TargetEmail) }

    rule(target: %i[webhook_id target_email_id]) do |webhook_id, target_email_id|
      webhook_id.filled? | target_email_id.filled?
    end
  end
end
What do you think? :)
The only thing that bothers me is the model class "hardcoded"
But that won't change that often, so it's OK I suppose
My initial idea was to somehow incorporate this:
class ApplicationSchema < Dry::Validation::Schema
  configure do |config|
    option :record
    option :user_repository, User
    option :customer_repository, Customer
    option :document_repository, Document
    option :document_content_repository, DocumentContent
    option :vendor_repository, Vendor
    option :template_repository, Template
    option :source_email_repository, SourceEmail
    option :parse_request_repository, ParseRequest
    option :target_email_repository, TargetEmail
    option :webhook_repository, Webhook

    config.messages_file = 'config/locales/validations.yml'
  end
...
end
Jaromír Červenka
@Cervajz
Nov 26 2018 16:52
Is there any way of Dry::Validation returning only the keys which are part of the schema? I was under impression that this is done automatically, especially with .to_monad extension. But it looks like I was wrong. Or maybe that was some older version as I remember it worked.
I'd like to get rid of strong params
I am looking thru the documentation and source code and can't find any option (or method on Result object) which would help me with that. Or I am blind :))
MySchema.call({i_dont_want_you: 'xxx', customer_id: 1, parse_request_id: "0266fa8b-6878-44aa-ad2e-a1d6e9dffa9d", webhook_id: 1}).to_monad
=> Success({:i_dont_want_you=>"xxx", :customer_id=>1, :parse_request_id=>"0266fa8b-6878-44aa-ad2e-a1d6e9dffa9d", :webhook_id=>1})