Overriding presence true in User model - ruby-on-rails

I have the following in my models/user.rb:
validates :company, presence: true
validates :title, presence: true
I have a secondary view where I want to create a user but not require this user to enter a company and a title. How would I do that without modifying the main user.rb?
This is for Rails 3.2

You can do by declaring custom validations the way #BroiSatse has answered or when saving the user you can pass validate: false as argument, do this way
#user.save(:validate => false)

I usually do sth like:
class User < AR::Base
validates :company, :title, presence: true, if: :validate_company_and_title?
def validate_company_and_title?
#validate_company_and_title.nil? || #validate_company_and_title
end
def skip_company_and_title_validation!
#validate_company_and_title = false
end
end
Then in your controller create action for given view you can do:
#user.skip_company_and_title_validation!

Related

How to validates Rails column with self other column not blank?

I have a mode named Exam.
There are some columns in exames:
:title
:subject_id
:exam_type
I want to know how to implement this:
class Exam < ApplicationRecord
validates :title, presence: true
validates :subject_id, presence: true, if: :no_exam_type?
def no_exam_type?
self.exam_type == ""
end
end
That is to say, I want to create a exam:
Exam.create(title: "first exam", exam_type: "something")
The subject_id must be exist, when exam_type is blank, such as exam_type="" or just do:
Exam.create(title: "first exam", subject_id: 3)
because exam_type has a default blank value.
But the subject_id doesn't necessary provide, when exam_type not blank, such as exam_type="something".
Exam.create(title: "first exam", exam_type: "something", subject_id: 3)
I test it, but no lucky.
How to do that? Thanks appreciate.
In Rails 5 belongs_to associations default to optional: false. Which means that the model will automatically validate the presence of the association.
class Thing < ApplicationRecord
belongs_to :other_thing
end
Thing.create!
# => ActiveRecord::RecordInvalid: Validation failed: other_thing can't be blank
So you need to set the association as optional and make sure the column is nullable.
class Exam < ApplicationRecord
belongs_to :subject, optional: true
validates :title, presence: true
validates :subject_id, presence: true, if: :no_exam_type?
def no_exam_type?
!self.exam_type.present?
end
end
Have you tried like this.
validates :subject_id, presence: true, :if => exam_type.blank?
you can refer the doc here to suite your requirement
use validates_presence_of instead.
validates_presence_of :subject_id, if: :no_exam_type?
def no_exam_type?
self.exam_type.nil?
end

Validate for params for separate forms for 1 model

I have an issue with a model. I have a model that is updated through 2 forms (as 2 people need to enter separate data). Form 1 contains the first half of the required data and therefor only that data needs to be validated there.
I am having trouble finding a way to validate only the data entered in form 1. Below you'll find my subscription.rb model file.
class Subscription < ActiveRecord::Base
# werkgever form
if form_id == 'form1'
validates :email, presence: true
end
# werknemer form
if form_id == 'form2'
validates :name, presence: true
validates :city presence: true
end
end
I need the if statements to contain something that would make it so that only the values beloging to that form are validated so that i dont get errors on form2 when updating and vice versa.
I hope this is clear enough. Any help is appreciated.
Thanks.
You could set validations with condition:
attr_accessor :form_type
validates :email, presence: true, :if => :werkgever_form?
def werkgever_form?
form_type == 'werkgever'
end
:form_type is a virtual attribute, which is not saved in the database and needed only for validations. You can set this attribute as a hidden field in each form:
<%= form.hidden_field :form_type, 'werkgever' %>
attr_accessor :form_type
validates :email, presence: true, if: :check_if_form_one
validates :name, presence: true, unless: :check_if_form_one
validates :city presence: true, unless: :check_if_form_one
def check_if_form_one
/* Add your condition here
example: form_type == 'form1' */
end
You can set form_type from controller method or view page.

How to access the parameter being validated

In the following example, is there a way to retrieve the name of the parameter being currently validated inside the if proc ?
class MyModel < ActiveRecord::Base
with_options if: proc{|o| "how to retreive the parameter being validated here?"} do
validates :param_1, presence: true
validates :param_2, presence: true
end
end
I would like to avoid this kind of solution:
class MyModel < ActiveRecord::Base
validates :param_1, presence: true, if: proc{|o| o.need_validation?(:param_1)}
validates :param_2, presence: true, if: proc{|o| o.need_validation?(:param_2)}
end
If you wish to know name, and other data like option to validation, use validators:
app/validators/param_validator.rb:
ParamValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
# your validation code here...
end
end
The arguments say about themself.
Use it in a model:
validates :param_1, param: true
validates :param_2, param: true
If each of the validations are identical apart from the name, you could iterate over them:
class MyModel < ActiveRecord::Base
[:param1,:param2].each do |param|
validates param, presence: true, if: proc{|o| o.need_validation?(param) }
end
end
I'm pretty sure there is no easy answer to my question, I'll find an other way.

How to use with_options for conditional validation

How can I use with_options for conditional validation ?
My code is
with_options if: (AppUser::User.creator=="is_admin") do |admin|
admin.validates :first_name, :presence => true
admin.validates :last_name, :presence => true
end
I have already set creator method in application controller.
before_action :set_global_user
def set_global_user
if current_admin
AppUser::User.creator= "is_admin"
elsif current_user
AppUser::User.creator= "is_user"
else
AppUser::User.creator=nil
end
end
but I am getting
undefined method `validate' for false:FalseClass
what is wrong with this code.
because
(AppUser::User.creator == "is_admin")`
does not return an object but it is a boolean.
Try this (inside your model):
class User < ActiveRecord::Base
with_options if: (AppUser::User.creator == "is_admin") do
validates :first_name, presence: true
validates :last_name, presence: true
end
end
P.S: I recommend the use of the devise gem to manage user types like this:
devise and multiple “user” models.

Rails - How to disallow specific inputs in model validations?

My User model has an attribute called :profile_name which is used in routing profile page url's - domain.com/:profile_name . In order to prevent collision with my other views I want to make sure a User can't choose something like "friends" or "feed" as their profile name. How can I set this in validations?
/models/user.rb (currently):
...
validates :email, presence: true, uniqueness: true
validates :profile_name, presence: true,
uniqueness: true,
format: {
with: /^[a-zA-Z0-9_-]+$/,
message: 'Must be formatted correctly.'
}
...
The exclusion validation helper:
validates :profile_name, presence: true,
...,
exclusion: {
in: ["friends", "feed"],
message: "Profile name %{value} is reserved."
}
Use a custom validation method. You'd probably want to separate out the forbidden list, but I kept this extra concise.
class User < ActiveRecord::Base
validates :profile_not_forbidden
protected
def profile_not_forbidden
if ['friends','feed'].include?(profile_name)
errors.add(:profile_name, 'Forbidden profile name.')
end
end
end

Resources