Right so I have one user table with different users. I need to validate user tables on update prior to them moving onto the main site.
so far I've just done the following, is there a way I can block the validations depending on a role without doing a custom validation method, like with_options :on => :update
before_validation :check_role
if check_role = "developer" do |dev|
dev.validate :first_name, presence: true # this doesn't work btw...
end
def check_role
return self.role_type unless self.role_type == nil
end
I figure it out and this looks like the best way to do it:
class YourModel
with_options :if => lambda { |o| o.whatever == "whatever" } do |on_condition|
on_condition.validates_presence_of :address
on_condition.validates_presence_of :city
end
with_options :if => lambda { |o| o.condition_the_second == "whatever" } do |on_condition|
on_condition.validates_presence_of :foo
on_condition.validates_presence_of :bar
end
end
validates :first_name, presence: true, if: :developer?
def developer?
role == 'developer'
end
with_options :if => Proc.new {|user| user.role_type == 'developer'} do |developer|
developer.validates :first_name, :presence => true
end
Related
I have this password validation in my user.model.rb:
class User < ActiveRecord::Base
validates :password, presence: true, confirmation: true,
format: {:with => /^(?=.*[0-9])(?=.*[A-Z])(?=.*[&%$##*])[a-zA-Z0-9&%$##*]{8,}$/,
:multiline => true, :message => I18n.t('invalid_password')}
end
I want this validation to be called in each and every method but not in my update action.
I have a users_controller.rb that has a create and update action. I want it to check in the create action but not in the update action.
I also have a password_resets_controller.rb in which I want it to check in both create and update actions but not in users_controller update action. I am using the authlogic gem. Both controllers use the same model.
Please guide me on how to do this. Thanks in advance.
validates :password, :presence => {:on => :create}
OR
##here new_user is a method that you can create and use condionally
## or validates_presence_of :password, :if => :new_user?
validates_presence_of :password, :unless => :new_user?
def new_user?
//your code
end
OR Using with_options
class User < ActiveRecord::Base
has_many :roles
# Normal Validations
validates_presence_of :password
with_options :if => :customer? do |customer|
customer.validates_presence_of :password
end
def customer?
roles.any? { |role| role.name == "customer" }
end
end
Probably the most close answer can be:
class User < ActiveRecord::Base
validates :password, presence: true, if: :not_persisted?
def not_persisted?
!self.persisted?
end
end
This code will actually trigger the validation only if the object is not persisted (on create)
I'm trying to create a validation statement that validates an object if service_area is present UNLESS service_area_radius==0
Here's the statement I created, which doesn't work:
validates :service_area, :presence => true, unless: "service_area_radius==0"
http://railscasts.com/episodes/41-conditional-validations
Like this:
validates_presence_of :password, :if => :should_validate_password?
validates_presence_of :country
validates_presence_of :state, :if => :in_us?
attr_accessor :updating_password
def in_us?
country == 'US'
end
def should_validate_password?
updating_password || new_record?
end
validates :service_area,
presence: {message: "Area Radius is missing."}, if: :radius_found?
private
def radius_found?
service_area_radius > 0
end
The validation for service_area will be executed if radius_found? returns true.
radius_found? will return true when the service_area_radius(attribute) hold value > 0.
Adding a custom message with message: option, when the validation fails.
When using state_machine, how can you conditionally validate fields in the below way?
state :unlit do
end
state :fire do
if is_big_fire?
validates_presence_of :big_log
end
if is_small_fire?
validates_presence_of :small_log
end
end
It seems to just ignore the if conditions and validate everything inside the state D:
The only sort of solution I came up with was
validates_presence_of :big_log, :if => Proc.new { |fire| fire.is_big_fire? }
But this gets nuts if there are more validations.
validates_presence_of :big_log, :if => Proc.new { |fire| fire.is_big_fire? }
validates :fire_epicness_rating, :inclusion => { :in => %w(epic whowa RUNFORTHEHILLS) }, :if => Proc.new { |fire| fire.is_big_fire? }
etc
Is there some nice way of neatly wrapping these in if blocks?
Grouping validations thanks to with_optionsis really neat. See here.
Here's an example using the with_options for group validation.
with_options :if => :driver? do |driver|
driver.validates_presence_of :truck_serial
driver.validates_length_of :truck_serial, :maximum => 30
end
def driver?
roles.any? { |role| role.name == "driver" }
end
Source: http://rubyquicktips.com/post/411400798/conditional-validation-using-with-options-to-improve
I have a model with many validations that can be grouped based on various conditions. The brute force way to handle it would be:
validates_presence_of :attr1, :if => :condition1
validates_something :attr2, :if => :condition1
validates_something_else :attr3, :if => :condition1
...
validates_presence_of :attr4, :if => :condition2
validates_something :attr5, :if => :condition2
validates_presence_of :attr6, :if => :condition2
...
But that doesn't seem very DRY. Is there a good way to group the validations based on the conditions? The approach I came up with is:
class Condition1Validator < ActiveModel::Validator
def validate(record)
record.instance_eval do
validates_presence_of :attr1
validates_something, :attr2
validates_something_else :attr3
end
end
end
validates_with Condition1Validator, :if => :condition1
class Condition2Validator < ActiveModel::Validator
...
end
validates_with Condition2Validator, :if => :condition2
Can anyone think of a better way?
Update: the way I posted above is flawed in that you cannot have if, unless, etc on the nested validators. Jesse's solution is much better.
This approach is from the multi-step wizard, where you only want to validate if you are on that wizard step. Should work for you as well
class YourModel
with_options :if => lambda { |o| o.whatever == "whatever" } do |on_condition|
on_condition.validates_presence_of :address
on_condition.validates_presence_of :city
end
with_options :if => lambda { |o| o.condition_the_second == "whatever" } do |on_condition|
on_condition.validates_presence_of :foo
on_condition.validates_presence_of :bar
end
end
I'm working on a model that has two associations that need to be set when an object is created, EXCEPT in one case.
Basically, it needs to work like this.
class Example < ActiveRecord::Base
has_one :foo
has_one :bar
validates_presence_of :foo
validates_presence_of :bar, :unless => :foo == Foo.find_by_name('ThisFooDoesntLikeBars')
end
I'm not sure how to build the :unless condition here, as it needs to check whether :foo is a specific object or not.
How do you do something like this?
:unless accepts a Proc
validates_presence_of :bar, :unless => Proc.new { |ex| ex.foo == Foo.find_by_name('ThisFooDoesntLikeBars') }
:unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.
http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html
How about the following:
class Example < ActiveRecord::Base
has_one :foo
has_one :bar
validates_presence_of :foo
validates_presence_of :bar, :unless => Proc.new { |example| example.foo == Foo.find_by_name('ThisFooDoesntLikeBars') }
end