Regex : only string can be accepted nothing else ? - ruby-on-rails

I am working on ruby on rails here is the code for regex
string_regex = /[a-z]+\z/i
validates :name , :format => { :with => string_regex , :message => "should not contain special character" }
Attempts:
dbcda-> true
abjdkbcak-> true
jgh1213 -> false
1314134##$ -> false
jbh31$ -> false
,,,,,,, -> false
kjgh,g,, -> TRUE(Which should be false).

You need to use /\A[a-z]+\z/i since you don't want any special characters from the beginning of your string (^) to the end of it (\z)
For help, try http://rubular.com/
[Edit] Changed as mentioned by #2called-chaos

Related

How remove an extra space in string and convert to int type?

When I enter a price more than three digits, such as 1000, the js script makes the 1 000, 10 000, etc. It puts a space for the user's convenience. Validation display is not a numeric type. How convert to int type in this situation?
validates :price, numericality: { only_integer: true, allow_nil: true }
here is a slightly better solution that would still allow you to have nil values
(please note that nil.to_i is 0 as well as any "text".to_i is also 0)
def my_method(str)
Integer(str.gsub(/\s/, ''))
rescue ArgumentError => e
nil
end
Example of use:
my_method('1000')
=> 1000
my_method('1 000')
=> 1000
my_method(' ')
=> nil
my_method('some_text')
=> nil
my_method('1.000')
=> nil
my_method('1,000')
=> nil
If you want to treat . and , you can adapt the regex in gsub.
I found a solution:
2.3.0 :004 > "1 000".delete(' ')
=> "1000"
2.3.0 :005 > "1 000".delete(' ').to_i
=> 1000

Switching between two boolean values in Ruby

I have the following code in a controller action, which looks at a user, and changes a boolean value to the opposite value, so if the user is true then it becomes false, and vice versa:
if current_user.enable_access
current_user.update_attribute(:enable_access, false)
else
current_user.update_attribute(:enable_access, true)
end
Is there a neater way of writing this?
How about using the toggle method that was specifically intended for this?
current_user.toggle(:enable_access)
If you want to add persistence in one character, there's also the toggle! method.
current_user.toggle!(:enable_access)
In one line, if current_user.enable_access can be only true`false`:
current_user.update_attribute(:enable_access, !current_user.enable_access)
Here's something to meditate on:
false # => false
true # => true
!false # => true
!true # => false
foo = false # => false
!foo # => true
foo = !foo # => true
foo = nil # => nil
!foo # => true
foo = !nil # => true
foo = !false # => true
Notice !!, which is a convenient way to turn a value into a true/false:
foo = !!nil # => false
foo = !!false # => false
foo = 1 # => 1
!foo # => false
!!foo # => true
foo = 'a' # => "a"
!foo # => false
!!foo # => true
0 == 1 # => false
1 == 1 # => true
'a' == '' # => false
'a' == 'a' # => true
These are the building blocks for comparisons in Ruby.
While the answer by #Зеленый is absolutely correct I wondered, that there is no DRY way to accomplish such a silly task.
The problem is that true and false in Ruby are instances of different classes, TrueClass and FalseClass respectively. That said, one can not just switch the boolean value inplace.
But what we can imagine, mediating at update_attribute source? Probably this is a shortest way to accomplish your task (please, do not use it at home, it’s a joke after all.)
current_user.tap do |cu|
cu.enable_access ^= true
end.save validate: false
I just reinvented toggle!, thanks #Dremni for pointing this out.
current_user.toggle!(:enable_access)
http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-toggle-21
I believe the DRY way to accomplish it would be to use:
current_user.enable_access = !current_user.enable_access
Then you could just write a method on a model and call it from any controller.
user.rb
def enable_user_access
self.enable_access = !self.enable_access
end
then calling it from a controller
current_user.enable_user_access

Trying to write REGEX for username validation in Rails

I'm trying to write a regular expression in Ruby (Rails) so that a username's characters only contains numbers and letters (also no spaces).
I have this regex, /^[a-zA-Z0-9]+$/, but it doesn't seem to be working and I get an error in Rails that says "The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?"
My full code for this implementation in my user.rb model is:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_USERNAME_REGEX = /^[a-zA-Z0-9]+$/
validates :username, presence: true, length: { maximum: 20 },
format: { with: VALID_USERNAME_REGEX },
uniqueness: { case_sensitive: false }
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, length: { minimum: 6 }
end
What am I doing wrong and how I can fix this regex so that it only is valid for numbers and letters and no spaces? Thanks.
Short answer: use /\A[a-zA-Z0-9]+\z/ instead (as VALID_EMAIL_REGEX is using).
Long answer: the ^ and $ anchors will match the beginning and end of a line in a string. That means that if your string consists of multiple lines of alphanumeric characters they will match:
/^[a-zA-Z0-9]+$/ =~ "Ana\nBob\nClara\nDaniel" #=> 0 (matches)
The \A and \z on the other hand will match the beginning and end of a string, hence it will prevent a possible attack by a user sending a multiline string (like in the previous example).
/\A[a-zA-Z0-9]+\z/ =~ "Ana\nBob\nClara\nDaniel" #=> nil (doesn't match)
/\A[a-zA-Z0-9]+\z/ =~ "Erika" #=> 0 (matches)
All you have to do is follow the error message. Replace ^ (start of line anchor) with \A (start of string anchor), and $ (end of line anchor) with \z (end of string anchor). Other than that, your regex works as is.
\A[a-zA-Z0-9]+\z
Rails has this security concern because unlike some languages, ^ and $ only match the beginning/end of a single line, rather than the entire string.
This illustrates an example of this possible exploit:
str = "malicious_code()\naValidUsername"
str.match(/^[a-zA-Z0-9]+$/) # => #<MatchData "aValidUsername">

How do you return a boolean value for a regexp scan of an integer?

I'm looking through my object attributes for culprits that are not :
^[1-3]{3}$
What is the method used to scan integers for regexp?
Some examples:
124.to_s.match(/^[1-3]{3}$/)
=> nil
123.to_s.match(/^[1-3]{3}$/)
=>#<MatchData "123">
Since nil is considered as false, you have your boolean.
Ex:
"no yo" if 124.to_s.match(/^[1-3]{3}$/)
=> nil
"yo!" if 123.to_s.match(/^[1-3]{3}$/)
=> "yo!"
You may use also one of the following:
def is_pure_integer?(i)
i.to_i.to_s == i.to_s
end
or
'132' =~ /^\d+$/ ? true : false

How to determine if a string is a number?

What is the easiest way to find out in Rails 3 whether a string str contains a positive float number or not ? (str is not an attribute in an active-record model)
It should work like this:
str = "123" => true
str = "123.456" => true
str = "0" => true
str = "" => false
str = "abcd" => false
str = "-123" => false
Here's one idea:
class String
def nonnegative_float?
Float(self) >= 0
rescue ArgumentError
return false
end
end
However, since you already seem to have a pretty good idea of what a nonnegative float number looks like, you could also match it against a Regexp:
class String
def nonnegative_float?
!!match(/\A\+?\d+(?:\.\d+)?\Z/)
end
end
You can match it against a regular expression.
str === /^\d+(\.\d+)?$/

Resources