Validates presence of THIS or THAT - ruby-on-rails

I have a form where the user is prompt to enter a title and either :this or :that. A user can't enter both fields.
<% f.input :title%>
<% f.input :this %>
<% f.input :that%>
for my :title i have in my Model
validates :title, :presence => true
How can i pass a validation for either :this or :that

You can do this
validates :that, :presence => true, :if => Proc.new {this.blank?}
validates :this, :presence => true, :if => Proc.new {that.blank?}

Wouldn't just the first line be sufficient?
validates :that, :presence => true, :if => Proc.new {this.blank?}
If 'this' is blank and so is 'that', the first line would fail validation, so you wouldn't need the second line.

Related

Active Record Model Validation if email is blank or empty

In sign up page I want to validate user's email if user enter invalid email or email textbox left blank and want to show error message Enter your email address
My User Model:
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
With the above regex, I am validating email but do not know how to add and display error meesage.
Kindly help me. Thanks.
Just try:
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email,
:presence => {:message => "Enter your email address!" },
:format => { :with => VALID_EMAIL_REGEX, :message => "Enter a valid Email address !"}
:uniqueness => {:case_sensitive => false, :message => "Email already exists!"}
To view these error, use the default error helper provided by Rails (<%= f.error_messages %> ).
<%= form_for #user, :url => {:controller=>"users", :action => "sign_up" } do |f| %>
<%= f.error_messages %>
---form fields and contents --
<%end%>
Hope it helps :)
For the Error Message,you can simply add message: 'your message'Just do like this.
If you want to provide a separate Error Messages,then you have to split the validations.
validates :email, presence: true, :format=> { :with=> VALID_EMAIL_REGEX , :message=> 'Enter your Email Address' }
validates :email, uniqueness: {:case_sensitive => false, :message => 'Please provide a valid Email' }

Rails 3 Active record validation error messages with unwanted/extra characters

I'm workin on ROR app using Rails 3.2.9 and I'm getting the error messages for a sign up page in my app as follows
<li>Login is too short (minimum is 3 characters)</li><li>Email is too short (minimum is 7 characters)</li><li>Email is invalid</li><li>Password can't be blank</li><li>Password is too short (minimum is 4 characters)</li><li>Password is invalid</li><li>Password confirmation can't be blank</li>
These are the default messages of Active Record Validation . (ref: http://guides.rubyonrails.org/active_record_validations_callbacks.html )
This app was previously written in Rails 2 and later migrated to rails 3. I have changed the validates_presence_of commands to validates : password , :presence=>true etc in accordance with rails 3 .
In the view ( signup.html.erb) error_messages_for is rendering these msgs. It is deprecated from rails 3.
Can anyone tell me what needs to be used instead of error_messages_for in the view and all code needs to be changed correspondingly for getting the error msgs right..
Here's the code (not complete)
user.rb in app/model
class User < ActiveRecord::Base
has_many :excel_files # One user may have many excel files
has_one :user_access_validity# One user may have one license period
# Virtual attribute for the unencrypted password
attr_accessor :password
attr_accessible :login
attr_accessible :email
attr_accessible :password
attr_accessible :password_confirmation
attr_accessible :company
#changes of 'validates' in accordance with rails 3:
validates :login, :presence => true,
:length => { :within => 3..40},
:uniqueness => { :case_sensitive => false },
:format => { :with => /^([a-z_0-9\.]+)$/i },
:on => :create,
:if => :is_login_entered?
validates :email, :presence => true,
:length => { :within => 7..100},
:uniqueness => { :case_sensitive => false },
:format => {:with => /^([a-z]+((\.?)|(_?))[a-z0-9]+#(mindtree.com|rvce.edu.in))$/i},
:on => :create,
:if => :is_email_entered?
validates :company, :presence => true,
:format => { :with =>/(mindtree|RVCE)/i},
:format => { :with => /^([a-z]+)$/i },
:on => :create,
:if => :is_company_entered?
#validates_presence_of :login, :email, :company
on => :create, :if => :is_login_entered?
validates :password, :presence => true,
:length => { :within => 4..40 },
:confirmation => true,
:format => { :with => /^([a-z0-9#!#\$]+)$/i },
:on => :create,
:if => :password_required?
validates :password_confirmation, :presence => { :if => :password_required? }
#validates_presence_of :password_confirmation, :if => :password_required?
before_save :encrypt_password
.
.
.
In signup.html.erb
<font color=red>(Fields marked * are mandatory)</font><h3>Sign me up!</h3>
<br>
<span class='error'><%= error_messages_for (#user) %></span>
<%= form_for :user do |f| -%>
<p><label for="login"><span class='redcolor'>*</span>Login</label><br/>
<%= f.text_field :login %></p>
<p><label for="email"><span class='redcolor'>*</span>Email</label><br/>
<%= f.text_field :email %></p>
<p><label for="password"><span class='redcolor'>*</span>Password</label><br/>
<%= f.password_field :password %></p>
<p><label for="password_confirmation"><span class='redcolor'>*</span>Confirm Password</label><br/>
<%= f.password_field :password_confirmation %></p>
<p><label for="company"><span class='redcolor'>*</span>Company</label><br/>
<%= f.text_field :company %></p>
<p><%= submit_tag 'Sign up' %></p>
<% end -%>
Solution
Got the following code from http://www.rubydoc.info/github/edavis10/redmine/ApplicationHelper:error_messages_for which shud be added in application_helper.rb and corresponding change in html.erb file as <%= error_messages_for (#user) %>
Code:
def error_messages_for(*objects)
html = ""
objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("##{o}") : o}.compact
errors = objects.map {|o| o.errors.full_messages}.flatten
if errors.any?
html << "<div id='errorExplanation'><ul>\n"
errors.each do |error|
html << "<li>#{h error}</li>\n"
end
html << "</ul></div>\n"
end
html.html_safe
end
http://guides.rubyonrails.org/active_record_validations_callbacks.html
if you read this guide you will see that in you form you can use form.error_messages
Solution for the question is added below the question

Handling model requirements within the same view?

First and foremost, thanks for taking time to read and respond to my questions. I really appreciate it.
I'm not looking for the exact code on how to achieve the following but more of a direction or path I should follow.
Users that are logged in can create different courses. I've added a requirement (a provider) for each course and I want the user to have at least one provider associated (using rolify for this) to them before doing so but I'd like this to be on the same view (courses#new)
I've tried the following:
Nested forms (Doesn't work since I require at least one provider upon course creation)
Adding the providers#new in a modal on the page (can't call a controller from another one using form_form(#provier)
I've thought of the following:
Redirect the users to providers#new if they haven't created one first
Add a modal with a form_tag element that creates a provider and then refreshes the underlying page.
What are your thoughts? Better ideas?
Thanks!
Francis
My courses#new (_form) view
<%= simple_form_for(#course) do |f| %>
<%= f.error_notification %>
<%= f.input :name %>
<%= f.input :description, as: :text, input_html: { rows: '2' } %>
<%= f.association :provider, :value_method => :id, collection: Provider.with_role(:provider_admin, current_user), input_html: { class: 'input-large' }, include_blank: false %>
<div class="form-actions">
<%= f.button :submit, :class => 'btn-primary' %>
<%= link_to "Cancel", :back, class: 'btn' %>
</div>
<% end %>
models/provider.rb
class Provider < ActiveRecord::Base
attr_accessible :description, :name
validates :name, :presence => true
validates :description, :presence => true
validates :name, :length => { :minimum => 6, :maximum => 100 }
validates :description, :length => { :minimum => 6, :maximum => 100 }
has_many :courses
end
models/course.rb
class Course < ActiveRecord::Base
attr_accessible :description, :name, :provider_id
validates :name, :presence => true
validates :name, :length => { :minimum => 6, :maximum => 100 }
validates :description, :presence => true
validates :description, :length => { :minimum => 6, :maximum => 256 }
validates :provider_id, :presence => true
belongs_to :provider
has_many :sessions, :dependent => :destroy
end
I like the idea where you do a redirect in courses#new to providers#new when !current_user.provider.any?.
But I would probably go the nested forms way. You can use one form to create a new course and a new provider if a user doesn't have a provider. Have a look at http://railscasts.com/episodes/196-nested-model-form-revised to get a quick idea. I think that this would be best UI wise.

Validate fields only if virt_attribute is false

I have such model:
class Order < ActiveRecord::Base
attr_accessible :**** :phone_number, :receiver, :shipping_id, :street, :totalcost, :user_id, :zip, :use_user_data
attr_accessor :use_user_data
validates :city, :presence => {:message => I18n.t(:city_not_chosen)}
validates :zip, :presence => {:message => I18n.t(:zip_not_chosen)}
validates :street, :presence => {:message => I18n.t(:street__not_chosen)}
validates :building, :presence => {:message => I18n.t(:building_not_chosen)}
validates :phone_number, :presence => {:message => I18n.t(:phone_number_not_chosen)}
validates :receiver, :presence => {:message => I18n.t(:receiver_not_chosen)}
end
As you can see i set in model some field which is non-db field (use_user_data) - virtual attribute...
But how to do, if :use_user_data is false, good and right validate, but when true didn't validate?
i try so:
validates :city, :presence => {:message => I18n.t(:city_not_chosen)}, :unless => :use_user_data
and so
with_options :unless => :use_user_data do |order|
order.validates :city, :presence => {:message => I18n.t(:city_not_chosen)}
end
but it doesn't help me... Why?
Also my form:
= form_for #order do |f|
%div
= f.label :use_user_data , "Использовать данные вашего профиля*: "
= label :use_user_data , "Да"
= f.radio_button :use_user_data, true, :required => true, :id => "use_user_data", :checked => true
= label :use_user_data , "Нет"
= f.radio_button :use_user_data, false, :required => true, :id => "dont_use_user_data"
Also when i write
validates :city, :presence => {:message => I18n.t(:city_not_chosen)}, :if => :use_user_data
i get validation messages... But how to do only if false? And why my solution didn't work?
The form passes "true" or "false" string to the object, not boolean true or false. Since it's a virtual attribute, no typecasting performed. In Ruby, both "true" and "false" are true, so you need to use something to typecast the value
with_options :unless => Proc.new{ |a| a.use_user_data == 'true' } do |order|
order.validates ...
end
Or
with_options :unless => :use_user_data? do |order|
order.validates ...
end
def use_user_data?
use_user_data == 'true'
end
You need to put your :if or :unless conditions in a lambda or Proc.
validates ..., :if => Proc.new { |a| a.use_user_data === false }
This causes the check against :use_user_data to not be evaluated until the above validates line is executed during validation (the Proc is passed as the value to the :if or :unless option to be evaluated by Rails). The Proc will receive the current model attributes as an argument, allowing you to check those attributes (in this case, :use_user_data being false).

Rails3: Display validate errors in a multi-model Form?

Is posible create this kind forms with displaying errors like a simple model?
http://i.imgur.com/8t6ef.png
I get create two models... but if I fill incorrectly the form.. the errors messages won't appears and error Rails screen say me, for example, "validation failed: field1 can't be blank..."
http://i.imgur.com/6KvVh.png
Models:
class Step < ActiveRecord::Base
#validates
validates :tree_id, :presence => true, :numericality => true
validates :is_first, :presence => true, :length => {:maximum => 1}
validates :status, :presence => true, :numericality => true
validates :step_type_id, :presence => true
#relations
belongs_to :step_type
belongs_to :tree
has_many :statements
accepts_nested_attributes_for :statements
end
class Statement < ActiveRecord::Base
#validates
validates :step_id, :presence => true, :numericality => true
validates :title, :presence => true, :length => {:maximum => 255}
validates :statement, :presence => true
validates :help, :presence => true
validates :is_last_version, :presence => true, :length => {:maximum => 1}
#relations
belongs_to :step
has_many :transitions
end
any example or suggestions?
Do you have the following lines in your view?
<% if #statement.errors.any? %>
<% flash[:notice] = "Please correct!" %>
<% for message in #statement.errors.full_messages %>
<li class="cf-messages-li"><%= message %></li>
<% end %>
<% end %>

Resources