Reputation: 34113
I'm trying to create a vanity url in a callback based on a user's name with the following method:
before_create :generate_vanity_url
def generate_vanity_url
vanity_url = self.name
vanity_url.gsub!(/[^\w]/,"")
end
The problem that occurs is that not only the variable vanity_url gets affected by the gsub! method, but the name attribute as well. What am I doing wrong?
Ps. the method is more extensive, but I have shortened it down for the purpose of clarity
Upvotes: 1
Views: 90
Reputation: 135415
You don't have to use .dup
, just don't use .gsub!
.gsub!
is a destructive method, meaning it modifies the original..gsub
is non-destructive and does not modify the originalSo yeah, something like this should do the trick
before_create :generate_vanity_url
def generate_vanity_url
@vanity_url = self.name.gsub /[^\w]/, ""
end
Also \W
is the same thing as [^\w]
so do this instead
before_create :generate_vanity_url
def generate_vanity_url
@vanity_url = self.name.gsub /\W/, ""
end
~ % pry
[1] pry(main)> str = "hello world"
=> "hello world"
[2] pry(main)> str.gsub /o/, "a"
=> "hella warld"
[3] pry(main)> str
=> "hello world"
[4] pry(main)>
Upvotes: 7
Reputation: 10592
To my knowledge (which may be poor) this is a result of copy-on-write. Do like that
vanity_url = self.name.dup
vanity_url.gsub!(/[^\w]/,"")
Simple example in irb
without .dup
...
> a = "asdf"
=> "asdf"
> b = a
=> "asdf"
> b.gsub!(/a/, 'q')
=> "qsdf"
> a
=> "qsdf"
> b
=> "qsdf"
... and with .dup
> a = "asdf"
=> "asdf"
> b = a.dup
=> "asdf"
> b.gsub!(/a/, 'q')
=> "qsdf"
> a
=> "asdf"
> b
=> "qsdf"
Upvotes: 3