There is a form that a user submits which then gets validated by the model. I only want the field "Province / State" to validate if the "Country" is either "CA" (Canada) or "US" (USA)
The form is set up a little differently because we are doing a multiple step from process.
Here is the controller.
def update
case step
when :step1
wizard_params = profile_params()
wizard_params[:wizard] = 'step1'
@profile = current_user.profile
@profile.update(wizard_params)
render_wizard @profile
end
private
def profile_params
# There are more params although I stripped them for the simplicity of this example
params.require(:profile).permit(:state_id, :country)
end
Profile.rb
belongs_to :state, :class_name => "ProvinceState", :foreign_key => :state_id, optional: true
I hard coded optional: true
but I only want optional:true if the user selected CA/US OR the field saved is CA/US.
I took a look at lambda and it could be something I need.
For Example:
belongs_to :state, :class_name => "ProvinceState", :foreign_key => :state_id, optional: lambda | obj | self.country == CA || self.country == US ? true : false
Unfortunately, you cannot (currently) provide a lambda to optional
- see the source code:
required = !reflection.options[:optional]
If required, Rails just adds a presence validation like this:
model.validates_presence_of reflection.name, message: :required
Therefore as a workaround, you could do this in two parts: First specify the association as optional
; then explicitly make it required for your condition:
belongs_to :state, :class_name => "ProvinceState", :foreign_key => :state_id, optional: true
validates :state_id, presence: true, if: ->{ %w[CA US].include?(country) }
If the logic gets significantly more complicated, you may wish to move this into a separate method/class instead of an inline lambda. See: Performing Custom Validations