Sign up page/form in Rails 3 not considering all fields required/mandatory - ruby-on-rails-3

My sign up page has login. email, password, password_confirm and company fields . All of them are supposed to be mandatory but when i click on sign up it is not checking if any fields except password and password_confirm are blank!! I dont understand what is the difference as in my app/models/user.rb file i have validates presence for all fields. Please help me
Here's code(required lines)
user.rb
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 :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? }
before_save :encrypt_password
#
# is_email_entered? : checks whether the email field is entered or not
# #params : none
# #return : true - if the email is entered
# false - if the email is not entered
#
def is_email_entered?
!self.email.blank?
end
#
# is_company_entered? : checks whether the company field is entered or not
# #params : none
# #return : true - if the company is entered
# false - if the company is not entered
#
def is_company_entered?
!self.company.blank?
end
#
# is_login_entered? : checks whether the login field is entered or not
# #params : none
# #return : true - if the login is entered
# false - if the login is not entered
#
def is_login_entered?
!self.login.blank?
puts "login"
end
protected
#
# password_required? : Checks whether either of the crypted_password and password field is blank
# #params : none
# #return : true - if either of the crypted_password and password field is blank
# false - if either of the crypted_password and password field is not blank
#
def password_required?
crypted_password.blank? || !password.blank?
puts "in pr?"
end
end
controller.rb
def signup
if logged_in?
flash[:notice] = "<span class='error'>You have already registered with us!</span>".html_safe
redirect_to :action => 'upload_file'
else
#user = User.new(params[:user])
return unless request.post?
#user.save!
self.current_user = #user
random_number = #user.generate_random_number
puts random_number
new_random_number = "c" + #user.id.to_s + random_number
#user.customerid = new_random_number
#user.created_at = get_current_datetime
# #user.updated_time = ''
#user.save
# save user's maximum access days
user_validity = UserAccessValidity.new
user_validity.user_id = self.current_user.id
user_validity.maximum_access_in_days = 90
user_validity.save
# redirect_back_or_default(:controller => '/account', :action => 'welcome')
redirect_to :controller => '/account', :action => 'welcome'
flash[:notice] = "<span class='success'>Thanks for registering!</span>".html_safe
end
end
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| -%>
<span class='error'><%= flash[:msg] %></span>
<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><%= f.submit 'Sign up', :name=> 'sign_up' %></p>
<% end -%>

The problem is that you pass an if option to your validation which also applies to the presence validation. Take for example the following
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?
is_login_entered? is called when validating the presence of login which conflicts with the validation which is why the validation is skipped. Change your validation to
validates :login, :presence => true, :on => :create
validates :login,
:length => { :within => 3..40},
:uniqueness => { :case_sensitive => false },
:format => { :with => /^([a-z_0-9\.]+)$/i },
:on => :create,
:if => :is_login_entered?
This way, the other validations will only run if a login is present.

Related

How to query three different tables to find out specific information

Ok, this is a triple table query, and I am very very confused in how to go about this, let along construct it.
I'm trying to find all the tutoring session tied to a specific email address.
The tables information is listed down beneath.
User, TutorSession, & SessionUser.
TutorSession belongs to User
Users has many SessionUser
Here are the attributes of each table:
User
:id => :integer,
:email => :string,
:encrypted_password => :string,
:reset_password_token => :string,
:reset_password_sent_at => :datetime,
:remember_created_at => :datetime,
:sign_in_count => :integer,
:current_sign_in_at => :datetime,
:last_sign_in_at => :datetime,
:current_sign_in_ip => :string,
:last_sign_in_ip => :string,
:created_at => :datetime,
:updated_at => :datetime,
:first_name => :string,
:last_name => :string,
:provider => :string,
:uid => :string,
:roles_mask => :integer,
:last_activity_at => :datetime,
:time_zone => :string,
:imported => :boolean,
:authentication_token => :string,
:getting_started_dismissed => :boolean,
:schedule_valid => :datetime
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["first_name"], :name => "index_users_on_first_name"
add_index "users", ["last_name"], :name => "index_users_on_last_name"
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
TutorSession
:id => :integer,
:session_code => :string,
:name => :string,
:moderator_pw => :string,
:attendee_pw => :string,
:session_type => :string,
:status => :string,
:started_at => :datetime,
:ended_at => :datetime,
:tutor_pickup_type => :string,
:recording_url => :string,
:created_at => :datetime,
:updated_at => :datetime,
:requested_by => :integer,
:subject_full_name => :string,
:student_dismissed => :boolean,
:school_id => :integer,
:tutoring_subject_id => :integer,
:tutor_appointment_id => :integer,
:white_board_status => :string,
:session_length => :integer
SessionUser
t.integer "tutor_session_id"
t.integer "user_id"
t.string "usertype"
t.string "url"
t.datetime "login_at"
t.string "logout_at"
t.string "flag"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "user_agent_string"
t.string "browser"
t.string "os"
end
add_index "session_users", ["tutor_session_id"], :name => "index_session_users_on_session_id"
add_index "session_users", ["user_id"], :name => "index_session_users_on_user_id"
EDIT
I made a mistaking in stating how the tables were related to each other. Sorry, my head is somewhere else.
SessionUser belongs to both user and tutor_session
TutorSession has many session_users
User has many session_users
Not sure what your model looks like, but should be as easy as:
User.find_by_email('someone#example.com').tutor_sessions
For this to work your models should look something like this:
class User < ActiveRecord::Base
has_many :sessions, :class_name => SessionUser
has_many :tutor_sessions, :through => :sessions
end
Basically, this query:
SELECT s.*
FROM users u
JOIN session_user su ON u.id = su.user_id
JOIN tutor_session s ON s.id = su.tutor_session_id
WHERE u.email = 'foo#bar'

Access all nodes in neo4j

On rails console i am trying to call
#invoice = Invoice.all
which returns me some object like
<Neo4j::Traversal::Traverser:0x817382>
but when i tried to loop over the object like
#invoice.each { |t| p t.number }
i got nil,but database contains data for invoice.
Invoice class
class Invoice < Searchable
include Neo4jrb::Paperclip
include LinkableEntity
include HeadsupNotify
enable_optimistic_locking
before_destroy :verify_links, :prepend => true
before_destroy :destroy_invoice_items
property :number, :type => :string
property :currency, :default => Money.default_currency.to_s
property :date, :pay_by_date, :type => :date
property :purchase_order_number
property :settle, :default => false
property :link_1, :link_2, :type => :string
index :number, :type => :fulltext
domain_property :details
money_property :total_cost, :receivable_amount
attr_protected :total_cost, :receivable_amount
attr_accessor :delink_receipt
validates :total_cost, :numericality => {:greater_than_or_equal_to => 0}
validates :receivable_amount, :numericality => {:greater_than_or_equal_to => 0}
validates :date,:number, :customer_id, :event_id, :project_id, :department_id,
:brand_id, :premise_id, :user_id, :currency, :presence => true
validates :link_1, :length => { :maximum => 250 }
validates :link_2, :length => { :maximum => 250 }
validate :number_uniqueness
validate :invoice_items_present
validate :invoice_items_currency
validate :issue_credit_notes_valid
validate :pay_by_date_valid, :unless => "date.nil?"
validate :check_not_linked, :on => :update
has_one(:event).from(Event, :invoices_for_event)
has_one(:project).from(Project, :invoices_for_project)
has_one(:department).from(Department, :invoices_for_department)
has_one(:brand).from(Brand, :invoices_for_brand)
has_one(:premise).from(Premise, :invoices_for_premise)
has_one(:user).to(User)
has_one(:customer).from(Customer, :invoices_for_customer)
alias :party :customer
has_n(:invoice_items).to(InvoiceItem)
has_n(:receipts).from(Receipt, :paid_invoices)
has_n(:issue_credit_notes).from(IssueCreditNote, :credit_notes_for_invoice)
has_one(:invoices_for_settle).to(Settle)
links :receipts, :issue_credit_notes,:invoices_for_settle
has_neo4jrb_attached_file :photo
{:customer => :name, :event => :name, :department => :name, :project => :name, :brand => :name,
:premise => :name, :user => :email}.each do |target, method|
delegate method, :to => target, :prefix => true, :allow_nil => true
end
accepts_id_for :customer, :event, :project, :department, :brand, :premise, :user
accepts_nested_attributes_for :invoice_items, :allow_destroy => true
validates_associated :invoice_items
validates :customer_name, :presence => true, :length => { :maximum => 100 }
validates :event_name, :presence => true, :length => { :maximum => 100 }
validates :premise_name, :presence => true, :length => { :maximum => 100 }
validates :project_name, :presence => true, :length => { :maximum => 100 }
validates :brand_name, :presence => true, :length => { :maximum => 100 }
validates :department_name, :presence => true, :length => { :maximum => 100 }
validates :link_1, :length => { :maximum => 250 }
validates :link_2, :length => { :maximum => 250 }
after_validation :set_total_cost
serialize :methods => :invoice_items
before_validation :delink
Can anyone please help me with this?
Thanks in advance.
I'm not exactly sure of how to do this with Ruby On Rails, but if your Invoice objects (nodes) are in a lucene full text index, you could use a Cypher query to return all Invoices.
Something like:
START invoices=node:Invoices('name: *') RETURN invoices;

Authlogic - how to set password_confirmation only for update?

I am trying to set up the password confirmation only on the page, where the user change his password.
My model looks this way:
class User < ActiveRecord::Base
attr_accessor :password_confirmation
acts_as_authentic do |c|
c.validate_login_field = false
c.validate_password_field = false
c.require_password_confirmation = true
c.logged_in_timeout(15.minutes)
end
validates :name, :presence => {:message => 'cannot be blank.'}, :allow_blank => true, :length => {:minimum => 3, :maximum => 40}, :on => :create
validates :email, :presence => {:message => 'address cannot be blank.'}, :allow_blank => true, :format => {:with => /\A[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]+\z/, :message => 'address is not valid. Please, fix it.'}, :uniqueness => true
validates :password, :presence => {:message => 'cannot be blank.'}, :allow_blank => true, :length => { :minimum => 6, :maximum => 40}, :on => :create
validates :password_confirmation, :presence => {:message => 'cannot be blank.'}, :allow_blank => true, :length => { :minimum => 6, :maximum => 40 }, :on => :update
end
and my method that saving new password:
def change_password
#user = current_user
if #user.valid_password?(params[:user][:old_password])
if #user.update_attributes(params[:user].reject{|key, value| key == "old_password"})
flash[:notice] = 'Your password was successfuly changed.'
redirect_to :back
else
flash[:warning] = 'You did not fill twice your new password correctly. Please, fix it.'
redirect_to :back
end
else
flash[:warning] = 'Your old password is WRONG! What is your malfunction!?!'
redirect_to :back
end
end
My problem is, that if I set the form the old password, then new password (eg. new_password) and then the confirmations of the new password (eg. new_password1), so the new password is changed & saved into the database - but it shouldn't, because the new password and the confirmation of the new password aren't the same...
How I should set up the validation rules or, where could be a problem?
Thanks for advices
You need to validate the password only if it's being changed. If it's not being changed, then the validation for the password field should be skipped.
Railscasts.com episode #41 shows you how to do this.

validate email format only if not blank Rails 3

I want to validate the email only if the email has been entered.
I tried the following:
validates :email, :presence => {:message => "Your email is used to save your greeting."},
:email => true,
:if => Proc.new {|c| not c.email.blank?},
:uniqueness => { :case_sensitive => false }
However this does not work as it stops error messages from showing when the email is left blank.
How can I validate the presence of the email when it is missing and ONLY validate the format when it has been entered?
This should do the trick.
validates :email,:presence => {:message => "Your email is used to save your greeting."}, :allow_blank => true,:uniqueness => { :case_sensitive => false }
Use:allow_blank => true or :allow_nil => true, :if => :email?
edit: fix typo.
You can write custom validation function:
class Model < ActiveRecord::Base
validate :check_email
protected
def check_email
if email.blank?
validates :email, :presence => {:message => "Your email is used to save your greeting."}
else
validates :email,
:email => true,
:uniqueness => { :case_sensitive => false }
end
end
end
or divide your validator into 2 separate validators with conditions:
validates :email,
:presence => {:message => "Your email is used to save your greeting."},
:if => Proc.new {|c| c.email.blank?}
validates :email,
:email => true,
:uniqueness => { :case_sensitive => false }
:unless => Proc.new {|c| c.email.blank?}
you can validate format if no precense required
:allow_nil => true

rails3.1 and formtastic 2.0.0.rc2 - undefined method `inputs'

I am using rails 3.1.0.rc3 with formtastic 2.0.0.rc2 and I am getting this error -
undefined method `inputs' for #<ActionView::Helpers::FormBuilder:0x000001059c2fb0>
Here is the block of code
= form_tag '#', :class => 'formtastic' do
= fields_for CustomFields::Field.new, :builder => Formtastic::Helpers::FormHelper.builder do |g|
= g.inputs :name => :attributes do
= g.input :_alias
= g.input :hint
= g.input :text_formatting, :as => 'select', :collection => options_for_text_formatting, :include_blank => false, :wrapper_html => { :style => 'display: none' }
= g.input :target, :as => 'select', :collection => options_for_association_target, :include_blank => false, :wrapper_html => { :style => 'display: none' }
Is this a bug ?
Thanks, Alex
You are trying to use a formtastic method here. When you are actually in a block for Rails's form builder.
You need semantic_form_for and formtastic in your Gemfile to use f.inputs for example..