Reputation: 175
I am a little new to the Ruby language and Rails framework but I really want to add some features to a registration page. Although this code works, I need to make it simpler and less cluttered but I am not sure where to begin here.
class User < ActiveRecord::Base
has_many :posts
has_many :comments
has_many :votes
has_secure_password validations: false
validates :username, presence: true, on: :create, length: {minimum: 5}, uniqueness: true
validates :username, presence: true, on: :update, length: {minimum: 5}, uniqueness: true
validates :password, presence: true, on: :create, length: {minimum: 5}
validates :password, presence: true, on: :update, length: {minimum: 5}
validates_format_of :username, on: :create, with: /\A[A-Za-z\d_]+\z/, message: "can only include letters and numbers"
validates_format_of :username, on: :update, with: /\A[A-Za-z\d_]+\z/, message: "can only include letters and numbers"
end
I want my users to be able to only include letters and numbers with no spaces for both their username and password. Also, they both need to be a minimum of 5 characters. Right now, only characters and numbers with no spaces works with my create action but it does not work for my update action. Any help would be greatly appreciated.
Upvotes: 0
Views: 241
Reputation: 239311
This is a very small model.
That said, there is lots of room for improvement, as you've introduced a ton of clutter.
There is no reason to specify on: :create
and on: :update
for two duplicate validations. If you just omit the on:
, then it will automatically apply to both create and update:
# Validate on both create AND update
validates :username, presence: true, length: { minimum: 5 }, uniquess: true
You can merge your format
validation into the first validates
line, and simplify the regex dramatically down to just \A\w*\z
, since \w
matches A-Za-z0-9_
:
validates :username, presence: true, length: { minimum: 5 }, uniquess: true,
format: { with: /\A\w*\z/ }
You should move the validation message into config/locals/en.yml
instead of having it directly in the model. User-facing strings have absolutely no place hard-coded in your source code, they should always reside in a localization file. See the i18n docs.
# config/locals/en.yml
activerecord:
errors:
models:
user:
attributes:
username:
too_short: "Your username is too short"
too_long: "Your username is too long"
All told, your model should look like this (note you should be specifying a maximum length validation as well as a minimum):
class User < ActiveRecord::Base
has_many :posts
has_many :comments
has_many :votes
has_secure_password validations: false
validates :username, presence: true,
length: { within: 5..20 },
uniqueness: true,
format: { with: /\A\w*\z/ }
validates :password, presence: true,
length: { within: 5..20 }
end
Upvotes: 1
Reputation: 10111
class User < ActiveRecord::Base
has_many :posts
has_many :comments
has_many :votes
has_secure_password validations: false
validates :username, presence: true, length: {minimum: 5}, uniqueness: true
validates :password, presence: true, length: {minimum: 5}
validates_format_of :username, with: /\A[A-Za-z\d_]+\z/, message: "can only include letters and numbers"
end
if you do something like this
Upvotes: 0