Rails form validation conditional bypass
In my opinion this is the best way to do it:
class FooBar < ActiveRecord::Base
validates_uniqueness_of :foo, :bar, :unless => :force_submit
attr_accessor :force_submit
end
then in your view, make sure you name the submit tag like
<%= submit_tag 'Resubmit', :name => 'foo_bar[force_submit]' %>
this way, all the logic is in the model, controller code will stay the same.
Skip validation on few fields
It seems to be such a simple question but the longer I think about it the more possible solutions come up. I have a hard time to tell which one is the DRYest. The quick and dirty solution would be to add a hidden boolean field xyz
in the doctor's form. You'd have to add that attribute on the bottom of your controller if you are using Rails 4. With that you could do something like this in your model:
validates :name, presence: true
validates :email, presence: true, unless: ->(patient){patient.xyz.present?}
How to skip validation in a validated field in one from conditionally?
It sounds like you're saying that all of the fields are required (all of them have validates_presence_of
) and so your form won't submit because there's always one field that isn't present. Of course it won't, in that case.
The obvious solution is: don't enforce the presence of every field. Perhaps what you want is to validate that at least one of :director and :producer is present. Take a look at conditional validation.
ETA: example
validates_presence_of :director, :if => "producer.blank?"
validates_presence_of :producer, :if => "director.blank?"
How can I do conditional validation in a Ruby on Rails Model?
By default all inputs are required. When the form object includes
ActiveModel::Validations (which, for example, happens with Active
Record models), fields are required only when there is presence
validation. Otherwise, Simple Form will mark fields as optional. For
performance reasons, this detection is skipped on validations that
make use of conditional options, such as :if and :unless.And of course, the required property of any input can be overwritten
as needed:
<%= simple_form_for @user do |f| %>
<%= f.input :name, required: false %>
<%= f.input :username %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
Try to put all the inputs as required: false. That should allow skip simple_form validations and the data came into the controller and the model can be filtered or/and validated and every other things you want to do before persist.
In the model class you can use several ways of validations for example:
you also can use the :if and :unless options with a symbol corresponding to the name of a method that will get called right before validation happens. This is the most commonly used option.
for example
class Participant < ApplicationRecord
belongs_to :study
validates :name, presence: true
validates :company, presence: true
validates :time_zone, presence: true
validates :mobile_number, presence: true if: :channel_is_sms?
validates :email, presence: true if: :channel_is_email?
def channel_is_sms?
channel == "sms"
end
def channel_is_email?
channel == "email"
end
end
or also you can use custom validator where you do all that you need validate. for example
class MyValidator < ActiveModel::Validator
def validate(record)
unless record.channel == 'sms'
...
... actions here
...
end
end
end
class Person
include ActiveModel::Validations
validates_with MyValidator
end
How to Bypass Model Validation Based Upon Object Attribute?
You can do it by passing a validate: false to your save method. Like this
def create
if params[:challenge][:someday] == "1" # I had to use "1" instead of "true" for this conditional to work
@item = item.new(item_params)
@item.save(validate: false)
else
# brings to create.html.erb
end
end
One more thing to note, it you're using 1
inside quotes, that's a string, and won't be considered as a boolean, unless you get it as a string in your params. :)
Conditional Rails Form Validation
Your problem is within the way you've structured your column names / model attributes.
Ideally you should change your attribute names on your model to :commission_method
and :commission_rate
. This allows for greater flexibility. Then in your view you can achieve what you're looking for with a radio button. You can store your :commission_rate
as a decimal in the db.
<%= f.radio_button :commission_method, "Fixed" %>
<%= f.radio_button :commission_method, "Percentage" %>
<%= f.number_field :commission_rate %>
In your view files if you need to switch between showing a fixed amount and a percentage you can just do:
<% case @sales_associate.commission_method %>
<% when 'Fixed' %>
<span>Fixed: <%= number_to_currency(@sales_associate.commission_rate) %></span>
<% when 'Percentage' %>
<span>Percentage: <%= "% #{@sales_associate.commission_rate}" %></span>
<% end %>
However, you "could" write a custom validation method that throws an error if both attributes were assigned.
In whatever model:
class SalesAssociate
validate :only_one_selected_commission
def only_one_selected_commission
errors[:base] << "Please select only one form of commission" if self.commission_fixed.present? && self.commission_percentage.present?
end
end
Rails Skip Validation For Nested Attribute if condition is true
aquarium.rb
has_many :fishes
accepts_nested_attributes_for :fishes,
attr_accessor :skip_fishes_ratio_validation
fish.rb
belongs_to :aquarium
validates :ratio, :numericality => { :greater_than => 0 }, unless: proc { |f| f.aquarium&.skip_fishes_ratio_validation }
then in aquariums_controller.rb
def some_action
@aquarium = Aquarium.new(aqua_params)
@aquarium.skip_fishes_ratio_validation = true
@aquarium.save
end
Conditional validation - 1 of 2 fields must be present
You're having a :
before true
, which is wrong:
validates :key, presence: true, unless: 'key_position.blank?'
validates :key_position, presence: true, unless: 'key.blank?'
or
validates :key, presence: true, unless: ->(obj) { obj.key_position.blank? }
validates :key_position, presence: true, unless: ->(obj) { obj.key.blank? }
Rails - Validation :if one condition is true
You can use a lambda for the if:
clause and do an or condition.
validates :description, presence: true, if: -> {current_step == steps.first || require_validation}
Related Topics
Notices for Sequence After Running Migration in Rails on Postgresql Application
How to Use Gems Not in a Gemfile When Working with Bundler
How Is Each_With_Object Supposed to Work
Error: Failed to Build Gem Native Extension (Ruby Extconf.Rb): MAC Osx
How to Improve Jruby Load Time
Why Won't a Longer Token in an Alternation Be Matched
Changing Every Value in a Hash in Ruby
Ruby Inject with Initial Being a Hash
Combine Array of Array into All Possible Combinations, Forward Only, in Ruby
How to Skip Has_Secure_Password Validations
How to Pass Data from a Controller to a Model with Ruby on Rails
Putting the Results of Pp (Or Anything Outputted to Console) into a String
Ruby Regex Error: Incompatible Encoding Regexp Match (Ascii-8Bit Regexp with Utf-8 String)
Where Should My Non-Model/Non-Controller Code Live