# ActiveRecord anti-patterns which you should avoid. Part 1: Conditional validations

Imagine that you develop an e-commerce platform. Your basic model is Order.

You would have some constraints which don't have to be valid before order is placed:
```
validates :order_items, length: {minimum: 1}, unless: :cart?
validates_presence_of :delivery_address, :delivery_type, :payment_type, unless: :cart?
``` 

You would alse need some validations which have to be checked on cart submition:
```
validates_inclusion_of :delivery_type, in: :available_delivery_types, on: :being_placed_via_cart
validates_inclusion_of :payment_type, in: :available_payment_types, on: :being_placed_via_cart
validates_acceptance_of :shop_rules_acceptance, :terms_of_anti_spam_policy_acceptance, on: :being_placed_via_cart
``` 
... but not always:

```
validates :electronic_order_rules_acceptance, acceptance: true, if: :electronic_order?, on: :being_placed_via_cart
``` 


Others should be checked only if the order is passed through an external system.
```
validates_presence_of :external_id, on: :being_placed_via_api
``` 

All the above leads to situations in which you get confused which validations would be triggered on certain save.

## So... What to do instead?

I suggest using form/command objects.


```
class PlaceOrderViaExternalApi < PlaceOrder
  validates_presence_of :external_id
end

class PlaceOrder < Command
  #...
end

class Command
  include ActiveModel::Model
  include ActiveModel::Attributes
  include ActiveModel::Validations
end

PlaceOrderViaExternalApi.new(order_params).valid?
``` 

You can initialize and validate them just like ActiveRecord objects but your model's code keeps cleaner and more maintainable.
