gsub within before_validation method is zeroing out my value - ruby-on-rails

I'm trying to remove dollar signs and commas from my form input (for example, $1,000.00 => 1000.00)
I have the following following line in my before_validation method in my model:
self.parents_mortgage = self.parents_mortgage.to_s.gsub!('$,','').to_i
This is causing any number to be put through to zero out. Is there something wrong with my syntax?

use tr:
self.parents_mortgage = self.parents_mortgage.to_s.tr!('$,','').to_i

self.parents_mortgage = self.parents_mortgage.to_s.gsub!('$','').gsub!(',','').to_i

self.parents_mortgage = self.parents_mortgage.to_s.gsub('/[\$,]/','').to_i
Because yes there was a problem with your syntax. Your regex needs the / wrapping, it needs to indicate that $ and , are a character group (by surrounding with []) and you need to escape the $

Related

trying to keep some escape characters.. but not others. ruby rails

I am having trouble formatting my string correctly. I am reading strings from a file and trying to use them as js code.
file_line = blah'blah"blah
string = line.gsub(/'/, "\\\'").gsub(/"/, "\\\"").dump
I want the output to be:
blah\'blah\"blah
But I cant seem to format it right. I have tried a bunch of things.
I'd use a single gsub matching both, ' and ", along with a block to prepend a \:
line = %q{blah'blah"blah}
string = line.gsub(/["']/) { |m| "\\#{m}" }
#=> "blah\\'blah\\\"blah"
puts string
Output:
blah\'blah\"blah
string = "blah'blah\"blah"
puts string.gsub(/'/,"\\\\'").gsub(/"/,'\"') # => blah\'blah\"blah
There's a whole lot of escaping going on here. To be honest I don't really understand the first one, but the second one is simple. I think in the first one we are escaping the backslash we want to add, and then escaping those two backslashes to avoid ruby interpretting them as a reference to the string. Or something. Trying to do a single level of escaping yields this:
puts string.gsub(/'/,"\\'").gsub(/"/,'\"') # => blahblah\"blahblah\"blah

Why doesn't my if/elsif statement create tagged links and send them to different routes?

My if/elsif statement is only executing the if, but not the elsif. I cannot understand why it is doing that. Sorry for not explaining how this works at all. The below edit explains it.
It is taking a string of text(a users post) and checking if it has a tag in it. If text has a tag then it will turn it into a link. The end result is the users string with the tags turned to links. The REGEX are the regular expressions to see if it has one of these tags #, #, $. They are not relevant as I know they are correct. For sample input it would be any type of post from twitter #user is #cool
REGEXS = [Supertag::Tag::USERTAG_REGEX, Supertag::Tag::HASHTAG_REGEX, Supertag::Tag::MONEYTAG_REGEX]
def linkify_tags(taggable_content)
text = taggable_content.to_s
REGEXS.each do
if text = text.gsub(Supertag::Tag::USERTAG_REGEX) {link_to($&, usertag_path($2), class: 'tag')}
elsif text = text.gsub(Supertag::Tag::HASHTAG_REGEX) {link_to($&, hashtag_path($2), class: 'tag')}
elsif text = text.gsub(Supertag::Tag::MONEYTAG_REGEX) {link_to($&, moneytag_path($2), class: 'tag')}
end
end
text.html_safe
end
Does anyone have any suggestions or explanations of why it doesn't work? It only is executing the first of the if/elsif
If you use if/else statements, you want to ask a question and perform one or the other based on the answer. It's called a conditional statement because you want a condition to be met before providing an action. Only after the answer is given you tell what to do next.
Now, what you are doing is the opposite. You tell what to do, without ever asking the question when to do it. No wonder it only runs the if statement, since this statement always returns true. The problem you face is that your first condition can never be false or nil.
As a rule of thumb, a question/condition should always have multiple possible answers, otherwise there is no point in asking.
This code:
if foo = any_value_other_than_false_or_nil
# this will always run
else …
# this will never run
end
This is because you are assigning the value to the variable foo, and the result is 'truthy' (unless the value you assign is nil or false).
I think perhaps you meant to use regex == … to test if the regex variable matches a constant, or perhaps regex =~ … to test if the regex variable finds a match within a string. Similarly, perhaps you mean text == … instead of text =, to compare if they are equal instead of changing the value of the variable.
The first one tells me there's an unexpected "{"
This is because Ruby (and I) have no idea what you mean by:
if foo = SomeConstant { some_code }
Perhaps if you ask another question describing your intention—and not just your code—others can help you achieve your end goal instead of answering questions about the symptoms.

before_save, strip a string

I'm trying to strip the whitespaces of the variable Username in my User Model.
I'm using
before_save do
self.username.strip!
end
but it doesn't seem to work, am i missing something ?
You'd rather update the setter instead of polluting your model with callbacks:
def username=(value)
self[:username] = value.to_s.strip
end
Btw, I prefer squish
If you want to remove only leading and trailing white space you can use .strip!
But as you said:
I'm trying to strip the whitespaces of the variable Username in my
User Model.
I think actually you want to remove all spaces following should do:
.gsub(/\s+/, "")
EDIT:
Oh yes, You can also use Rail's built-in method squish()
thanx to apneadiving for reminding

Replace "%20" with "-" in URL for rails

I'm developing a web application using rails.
For aesthetic purposes, i need to replace %20 with -
Before: http://localhost:3000/movies/2006/Apna%20Sapna%20Money%20Money
After: http://localhost:3000/movies/2006/Apna-Sapna-Money-Money
Is there anyway i can achieve this in rails?
You should use URI.parse to break it into pieces and then change only the path component:
require 'uri'
u = URI.parse(url)
u.path = u.path.gsub('%20', '-')
url = u.to_s
Just a simple gsub on the whole URL would probably work fine but a little extra paranoia might save you some confusion and suffering down the road. Also, if you're just replacing a literal string rather than a regular expression, you can use a String as the first argument to gsub and avoid some escaping issues:
The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. '\\d' will match a backlash followed by d, instead of a digit.
If your string is stored in the variable url you can use
url.gsub(/%20/, "-")
to return the string you want, or
url.gsub!(/%20/, "-")
to actually modify the value of url with the value you want.
https://github.com/FriendlyId/friendly_id
this is the best way to go about seo urls
You probably want to be saving "Apna-Sapna-Money-Money" within your Movies model as an attribute (I usually call these slugs). Then, to generate these, you might just need to replace spaces in the movie title with hyphens. Something like:
class Movie
before_create :generate_slug
private
def generate_slug
slug = title.gsub(" ", "-")
end
end
Then in your controller action you can simply do a Movie.find_by_slug!(params[:id]) call.
Basically, there should be no reason for users to ever arrive at a URL with %20 in it...

Stripping the first character of a string

i have
string = "$575.00 "
string.to_f
// => 0.0
string = "575.00 "
string.to_f
// => 575.0
the value coming in is in this format and i need to insert into a database field that is decimal any suggestions
"$575.00 "
We did this so often we wrote an extension to String called cost_to_f:
class String
def cost_to_f
self.delete('$,').to_f
end
end
We store such extensions in config/initializers/extensions/string.rb.
You can then simply call:
"$5,425.55".cost_to_f #=> 5425.55
If you are using this method rarely, the best bet is to simply create a function, since adding functions to core classes is not exactly something I would recommend lightly:
def cost_to_f(string)
string.delete('$,').to_f
end
If you need it in more than one class, you can always put it in a module, then include that module wherever you need it.
One more tidbit. You mentioned that you need to process this string when it is being written to the database. With ActiveRecord, the best way to do this is:
class Item < ActiveRecord::Base
def price=(p)
p = p.cost_to_f if p.is_a?(String)
write_attribute(:price, p)
end
end
EDIT: Updated to use String#delete!
So many answers... i'll try to summarize all that are available now, before give own answer.
1. string.gsub(/[\$,]/, '')
string.gsub!(/^\$/, '')
2. string[1..-1]
3. string.slice(0) # => "ome string"
4. s/^.//
Why (g)sub and regexp Just for deleting a character? String#tr is faster and shorter. String#delete is even better.
Good, fast, simple. Power of reverse indexing.
Hm... looks like it returns "S". Because it is an alias to String#[]
Perl? /me is cheking question tags...
And my advice is:
What if you have not dollar, but yena? Or what if you don't even have anything before numbers?
So i'll prefer:
string[/\d.+/]
This will crop leading non-decimal symbols, that prevent to_f to work well.
P.S.: By the way. It's known, that float is bad practice for storing money amounts.
Use Float or Decimal for Accounting Application Dollar Amount?
You could try something like this.
string = string[1..-1] if string.match(/^\$/)
Or this.
string.gsub!(/^\$/, '')
Remember to put that backslash in your Regexp, it also means "end of string."
you can use regex for that:
s/^.//
As laways, this is PCRE syntax.
In Ruby, you can use the sub() method of the string class to replace the string:
result = string.sub(/^./,"")
This should work.
[EDIT]
Ok, someone asked what's the gsub() is for:
gsub() acts like sub() but with the /g modifier in PCRE (for global replacement):
s/a/b/
in PCRE is
string.sub(/a/, "b")
and
s/a/b/g
is
string.gsub(/a/, "b")
in Ruby
What I'd use (instead of regular expressions) is simply the built-in slice! method in the String class. For example,
s = "Some string"
s.slice!(0) # Deletes and returns the 0th character from the string.
s # => "ome string"
Documentation here.

Resources