A couple of possible optimizations. I haven’t seen whether `errors.add`
adds repeatedly (I think it does in AR, but I haven’t played with Sequel
enough to be certain). I’d pull out the sales line checks into its own
method, and generalize the `errors.add` item.

def invalid_sales_line_entry?(name) # :yields: nothing, but the block is
your test.
  errors.add(name, "Not filled in") if yield
end

def validate_sales_line(line)
  invalid_sales_line_entry?(:sales_qty) { !draft? &&
line[:sales_qty].blank? }
  invalid_sales_line_entry?(:requested_qty) { submitted? &&
line[:requested_qty].blank? }
  invalid_sales_line_entry?(:sales_qty) { approved? &&
line[:approved_qty].blank? }
end

You can then do `validate_sales_line(line)` and reduce the amount of
duplication to:

if sales_line.kind_of?(Hash)
  validate_sales_line(sales_line)
elsif sales_line.kind_of?(Array)
  sales_line.each do |line|
    validate_sales_line(line)
  end
end

I might do something a little different using #any?, personally, but this
seems to be the right balance between readability and optimization.

-a

On Wed, Nov 2, 2016 at 10:40 AM, <[email protected]> wrote:

> I finally figured this out, perhaps there's a better way but this is, at
> least, working.
>
> The issue I was having is that the validation would work for single values
> OR for serialized multiple values but not both. The issue there was that it
> would return a hash for one value and an array of hashes for singles, and I
> couldn't figure out how to do that in one go.
>
> So here's my solution. Very welcome to suggestions otherwise but at least
> this is working (and doesn't appear to have a deleterious effect on testing
> speed)
>
> if sales_line.kind_of?(Array)
> sales_line.each do |line|
> errors.add(:sales_qty, "Not filled in") if !draft? &&
> line[:sales_qty].blank?
> errors.add(:requested_qty, "Not filled in") if submitted? &&
> line[:requested_qty].blank?
> errors.add(:approved_qty, "Not filled in") if approved? &&
> line[:approved_qty].blank?
> end
> elsif sales_line.kind_of?(Hash)
> errors.add(:sales_qty, "Not filled in") if !draft? && (!sales_line ||
> !sales_line[:sales_qty])
> errors.add(:requested_qty, "Not filled in") if submitted? && (!sales_line
> || !sales_line[:requested_qty])
> errors.add(:approved_qty, "Not filled in") if approved? && (!sales_line ||
> !sales_line[:approved_qty])
> end
>
>
>
> On Friday, July 29, 2016 at 12:35:56 PM UTC-4, [email protected] wrote:
>>
>> I have a model with a serialized column of data, and I need to make sure
>> that certain fields exist in the serialized data depending on different
>> criteria (I'm using the enum plugin for status)
>>
>> class Order < Sequel::Model
>>   enum :status, [:draft, :submitted, :approved]
>>   plugin :serialization
>>   serialize_attributes :json, :sales_line
>>
>>
>>   def validate
>>     super
>>     validates_presence :sales_line unless draft?
>>     # How can I validate that the sales lines also have a "sales_qty"
>> attribute?
>>   end
>>
>> end
>>
>> Basically, inside my serialized data of sales lines I have some fields.
>> Based on the order status I need to make sure that these fields are present:
>>
>> - "sales_qty" must be filled in unless the order is a draft
>> - "approved_qty" must be filled in if the order is approved
>>
>> Doing this if these were fields on a relation or on the order itself is
>> fairly straight forward but I'm not sure how to do it on serialized data.
>> Thanks!
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "sequel-talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/sequel-talk.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Austin Ziegler • [email protected][email protected]
http://www.halostatue.ca/http://twitter.com/halostatue

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to