I have the following code in models/micropost.rb
class Micropost < ActiveRecord::Base
belongs_to :user
validates :content, length: { maximum: 140}
validates :content, length: { minimum: 1 }
The first validation line is fine. However, in the second line I am trying to check for blank in content and something is going wrong? I think there's a problem with the multiple validates statements maybe? I'm pretty new to rails... :(
You can simply validate presence:
validates :content, length: { maximum: 140 }, presence: true
You can validate min and max length by using in range
validates :content, length: { in: 1..140 }
Related
Have many to many relationship but keep getting the same error: ActiveModel::UnknownAttributeError: unknown attribute 'employee_id' for EmployeeSkill. I've checked both my models and it seems like i have IDs for both so not sure what to do?
class Skill < ApplicationRecord
validates :skill_name, presence: true, length: { minimum: 3, maximum: 30}
validates_uniqueness_of :skill_name
has_many :employee_skills
has_many :employees, through: :employee_skills
end
...
class Employee < ApplicationRecord
before_save { self.email = email.downcase }
#validates :email, presence: true, length: { maximum: 30 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_many :employee_skills
has_many :skills, through: :employee_skills
end
...
class EmployeeSkill < ApplicationRecord
belongs_to :employee
belongs_to :skill
end
1) Check if in your migration files and database the corresponding id's are in place.
2) Restart the server (weird but sometimes is needed).
Your code looks good so I think is one of two cases I mention.
Regards,
With validation context we can do:
validates :title, presence: true, on: :published
validates :content, length: { maximum: 50 }, on: :published
Is it possible to wrap multiple validations that share a context something like the following?
on: :published do
validates :title, presence: true
validates :content, length: { maximum: 50 }
end
Yes, you can group validations using the with_options method:
with_options(on: :published) do |record|
record.validates :title, presence: true
record.validates :content, length: { maximum: 50 }
end
See the Rails Guides, this article and the sources for more info.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
(validates :name, presence: true, length: { maximum: 50 })
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 };
format: { with: VALID_EMAIL_REGEX };
uniqueness: { case_sensitive: false },
has_secure_password:
(validates :password, presence: true, length:{ minimum: 6 } )
end
Someone help me to figure out where this syntax has an error
In your User model try this:
class User < ActiveRecord::Base
before_validation { self.email = email.downcase! }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
Your model should looks like below.
class User < ActiveRecord::Base
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, presence: true, length:{ minimum: 6 }
has_secure_password
end
You probably also want to change this line:
before_save { self.email = email.downcase }
Into this:
before_validation { self.email = email.downcase }
The way this is going to go down is:
Validation
Before save callbacks
Actual save
So a user will use uppercase letters in his email, then save and the validations will fail because of the use of uppercase letters.
So you want to set his email to lower case letters BEFORE the validations and not after :-)
In our app's User model, we already have:
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
before_save { self.email = email.downcase }
validates :first_name, presence: true, length: { maximum: 50 }
validates :last_name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
Now, we need to add relationship associations to the model, namely:
has_many :roles, dependent: :destroy
has_many :agendas, through: :roles
Does it matter whether we include the latter go BEFORE or AFTER the former, in the model?
If so, what is the recommended / preferred / best way?
It doesn't matter, but the important thing is to be consistent. A usual best practice is to first do all you can to declare the class' structure, before you get in to any operational details. For example:
class User < ActiveRecord::Base
attr_accessor :remember_token, :activation_token, :reset_token
has_many :roles, dependent: :destroy
has_many :agendas, through: :roles
before_save :downcase_email
before_create :create_activation_digest
before_save { self.email = email.downcase }
validates :first_name, presence: true, length: { maximum: 50 }
validates :last_name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
end
Again, this is just one way to do things, but it's very common amongst Rails applications.
I have a form with 10 attributes.
Among them I have 4 attributes which I need to apply what I'd call a"mutually conditional presence" Active Record validation.
these attributes are
address_line_1
zipcode
state
country
It means that if the user fills ONE of them then ALL the others have to be present
So far I have only be able to say that if the user fills the first attribute "address line 1" then all the others must be present.
But it does not validate that all the MUTUAL presences in all possible combinations. For example if the user lets 'address line 1' empty but fills zipcode and leaves the other three empty, I want active recoird not to validate the form as he then should have been asked to fill the other three attributes. And so on with each of the attibutes.
How to do this?
Here is my current code
spec/models/users
validates :address_line_1,
presence: true,
length: { maximum: 100,
minimum: 3 }
validates :zipcode,
presence: true, if: :address_line_1?,
length: { maximum: 20,
minimum: 4}
validates :state,
presence: true, if: :address_line_1?,
validates :country,
presence: true, :address_line_1?,
length: { maximum: 50}
Just replace :address_line?condition with a check for one of the filled out fields:
validates :address_line_1,
presence: true, if: :address_entered?,
length: { maximum: 100,
minimum: 3 }
validates :zipcode,
presence: true, if: :address_entered?,
length: { maximum: 20,
minimum: 4
validates :state,
presence: true, if: :address_entered?,
validates :country,
presence: true, if: :address_entered?,
length: { maximum: 50}
def address_entered?
address_line_1.present? || zipcode.present? || state.present? || country.present?
end