I'm quite new to ruby/rails. I was wondering what is the best way to ensure that two people don't choose the same username. Here is my model at the moment:
class User < ActiveRecord::Base
validates :username, :presence => true
validates :password, :presence => true, :length => { :minimum => 7}
end
Note: I'm assuming it is best to place this type of code in the model. Correct me if I'm wrong.
There's a validation to make sure a field is unique. Just change your username validation to:
validates :username, :presence => true, :uniqueness => true
You should also add an index to your usertable, with uniqueness. This way, if people quickly press the username register button twice, you will also be protected at the database level
add_index :users, :username, :unique => true
This question has already been correctly answered but for future reference, APIDock has excellent Rails documentation here: http://apidock.com/rails. The search's autocomplete is fantastic.
The documentation for the validates method is here: http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates where you can find the :uniqueness => true option.
Related
Thank you for looking onto this. I have a rails 5 API application. I am using ActiveModel Validations to validate params.
I need to validate the keys of params. ie. all the keys are mandatory to keep the structure of request unique, but it can be blank(ie. the values)
I know the
validates :key presence: true
validation, but it is checking there is a value for that. As i said, it can have blank values.
I am using params.permit so that additional keys are not allowed
include ActiveModel::Validations
validates :key1, presence: true
def initialize
#key1 = "val"
#key2 = "val2"
params.permit(:key1,:key2)
end
I need to compel the user to do requests with all the parameters with blanks allowed
Thanks in advance
Hello you should add the allow_blank options to your model like this:
validates :key presence: true, :allow_blank => true
Hope it can help
From the doc you need to specify allow_blank like :
validates :key1, :presence => true, :uniqueness => { :allow_blank => true, :case_sensitive => false }
Hope this helps !
You can try like below:
validates :key, presence: true, allow_blank: true
allow_blank:
The :allow_blank option is similar to the :allow_nil option.This option will let validation pass if the attribute's value is blank?, like nil or an empty string for example.
Note: nil values will be allowed
I have two params :work and :grade. In the model, before saving I want to use validates_uniqueness_of to check given a unique work, there is only one grade. Grade can be the same for other work. How would I write this?
Edit:
validates_uniqueness_of :work, :scope => :grade
If you have a deprecated syntax warning, you can write it so:
validates :work, uniqueness: {scope: :grade}, presence: true
Edit:
It seems you need a two way checking, so perhaps adding this will work:
validates :grade, uniqueness: {scope: :work}, presence: true
Although under high load I've seen this fail, so best is to create a database constraint.
Hi I have a job model which has an string attribute called category. In the front end, I have a form with a dropbox where a user can fill out the category attribute with the selected value from the list. This is good enough front end validation for me, but now how will I do backend validation for the model?
I have dont other validations in the past for example:
validates :name, :presence => true
But is there anyway I can do something like
validates :category, :in => {"Food", "Drink", "Rental"}
You can do it like this:
validates :category, :inclusion => { :in => %w(Food Drink Rental) }
Or shorter:
validates :category, :inclusion => %w(Food Drink Rental)
Everything is in the documentation.
(A) Like this:
validates :network_id, :numericality => true
validates :direct_url, :presence => true
validates :domain_name, :presence => true
validates :merchant_id, :numericality => true
validates :is_paid_merchant, :presence => true
validates :is_top_merchant, :presence => true
validates :last_months_revenue, :presence => true,
:numericality => true
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :primary_category_id, :numericality => true
validates :url, :presence => true
validates :url_tag, :presence => true,
:length => { :maximum => 45 }
-OR-
(B) like this:
validates :network_id,
:merchant_id,
:last_months_revenue,
:primary_category_id, :numericality => true
validates :direct_url,
:domain_name,
:is_paid_merchant,
:is_top_merchant,
:last_months_revenue,
:name,
:url,
:url_tag, :presence => true
validates :name, :length => { :maximum => 50 }
validates :url_tag, :length => { :maximum => 45 }
In the first case each field has it's own validates clause and in the second it's based on what is being validated (fields that have multiple validations appear multiple times). The first case is also in alphabetical order so is a little more helpful to jump right to a specific field.
-OR-
(C) Am I just too anal retentive about how my code reads and looks?
I think the first style is better for the following reason:
It's most likely that you have a specific field name 'in mind' when working on a validation - or editing one - or adding a new validation for that field. So a system that lists each field and then all the validations for each one works well to read.
The other style - group validations together tends to lead to seeing a field in one spot but then having to search and scroll around for other validations for that field - and there's a good chance that you will not see or know about the other validations for that field which may be 'off-screen' and thus missed.
This also may not be that big a deal when initially building the application (when the first style might actually seem easier) but going forward when you are adding or removing or changing fields and validations (i.e. 'application building in the real world!') it will be easier and less error-prone if all the validations for a given field are together.
Another example of why B) is bad...
Imagine this:
validates :network_id,
:merchant_id,
:last_months_revenue,
:primary_category_id, :numericality => true
validates :network_id,
:direct_url,
:domain_name,
:merchant_id,
:url,
:url_tag, :presence => true
validates :network_id :uniqueness => true
See how field are repeated all over the place?
Now imagine removing network_id - yuch!
Now imagine adding another _id field that needs numericality, uniqueness and presence - yuch!
Another example - one might think (ok, I've done long ago), i'll group all the 'required's together and then put a nice comment for them and then all the uniquesness of's, with a comment header label for all of them, etc. So there is a 'standard' for developers to follow. The problem with an approach like this (apart from the previous comments) is that this is a 'local' standard that other programmers (both current and future) will need to understand and then... hopefully... follow. Much as I love them myself, personal standards like this often contribute to technical debt unless clearly thought out.
Personally I'd prefer the first style. Because I'd kick you for having to read through 30 lines of code to find out what validations are set on a single field.
For me better is A. One declaration for one attribute is not redundant but clear.
I have a model with a whole bunch of fields. Not all fields are used based on the user selecting a certain type of form. I have around 6 different types of forms so a field may be used on 4 of them.
Is there a way to group validation based on a element ie?
case xxx
when "form1"
validates :field1, :presence => true
when "form2"
validates :field1, :presence => true
when "form3"
validates :fiel2, :presence => true
end
I will be doing client side validation but I obviously will need server side as well to make sure they have submitted good data.
Any suggestions how this can be done ?
I'm using Rails3 with Mongoid 2.0
Thanks in advance!
Something like this?
validates :field1, :presence => true, :if => Proc.new { |foo| %w{form1 form2}.include?(foo.xxx) }
validates :field2, :presence => true, :if => Proc.new { |foo| %w{form1 form3}.include?(foo.xxx) }
validates :field3, :presence => true, :if => Proc.new { |foo| %w{form2 form3}.include?(foo.xxx) }
I see a problem with the model class having to have intimate knowledge of the views involved. If the forms in the views were named differently, the solution won't work. You will want to use "validation groups" like that used in ASP.NET. You could do some search on that and either find a similar solution for Rails or roll your own. Maybe this one will help: https://github.com/akira/validationgroup