0

This question has answered the question for a single column but how do you do it for multiple columns? I've got three columns (website, fb, twitter) that I want to prefix with http in case users don't input them in the form.

I tried this but it doesn't work:

before_save :sanitize_links

private

def sanitize_links
  website = self.website
  facebook = self.facebook
  twitter = self.twitter
  links = [website, facebook, twitter]
  links.each do |link|
    unless link.include?("http://") || link.include?("https://")
      link = "http://" + link
    end
  end
end

Update

I've tried the suggestion by KL-7 but unfortunately hit a little snag. How do I use the output of the array with before_save? I've tried the code below but it doesn't work.

before_save :sanitize_links

private

def sanitize_links
  links = ["website", "facebook", "twitter"]
  links.map! { |link| self.link =~ %r{\Ahttps?://} ? self.link : "http://" + self.link }
end

Update 2

I gave up. I'll just repeat it three times:

before_save :sanitize_links

private

def sanitize_links # prefix user-submitted links with http:// if missing
  self.website =~ %r{\Ahttps?://} ? self.website : self.website = "http://" + self.website
  self.facebook =~ %r{\Ahttps?://} ? self.facebook : self.facebook = "http://" + self.facebook
  self.twitter =~ %r{\Ahttps?://} ? self.twitter : self.twitter = "http://" + self.twitter
end
Community
  • 1
  • 1
hsym
  • 4,217
  • 2
  • 20
  • 30

1 Answers1

1

The problem is that

link = "http://" + link

in your code assigns a new value to the link variable withing the block, but doesn't change the corresponding element of the list.

To alter elements of the list in-place you can use Array#map!:

links.map! do |link|
  link.include?("http://") || link.include?("https://") ? link : "http://" + link
end

Another thing I'm a bit worried about is that include? will return true even if the given substring (e.g., 'http://' occurs somewhere in the middle of your string and not necessarily at the beginning. I'd rather use a regexp for that task:

links.map! { |link| link =~ %r{\Ahttps?://} ? link : "http://" + link }

Update

If link is an attribute of your model, then you should at least store it as an attribute and not as a local links variable:

self.links = links.map { |link| link =~ %r{\Ahttps?://} ? link : "http://" + link }
KL-7
  • 46,000
  • 9
  • 87
  • 74
  • I tried this in the rails console: `links = [shop.website, shop.facebook, shop.twitter]` `links.map! { |link| link =~ %r{\Ahttps?://} ? link : "http://" + link }` and it works but I can't make it work in rails app. Any help? – hsym Jul 08 '12 at 10:06
  • I'm guessing it just change the values in the array but doesn't translate it back in the output. How do I this? – hsym Jul 08 '12 at 10:13
  • How do you mean "doesn't translate it back in the output"? It changes elements of the `links` list by prepending `'http://'` where necessary. Then you can use this array however you want. – KL-7 Jul 08 '12 at 11:39
  • Yeah, it's actually my fault. I'm still trying to figure out how to use the array output with `before_save`. – hsym Jul 08 '12 at 12:57
  • Well, I think that's a different question. – KL-7 Jul 08 '12 at 12:59
  • I updated the answer, though, it's still not clear what is `links` in your case, why do you initialize it in `before_save` filter, and how exactly you want "to use the array output with `before_save`". If my update doesn't help, you better accept my answer to this question (as we solved your problem) and open a new question regarding `before_save` with a good description of what you want to achieve. – KL-7 Jul 08 '12 at 15:48
  • Um, I thought I've already stated this in my question above: "I've got 3 db columns (website, fb, twitter) that I want to prefix with http in case users don't input them in the form." That's why I'm using `before_save`. – hsym Jul 08 '12 at 15:54
  • Ok, in your code sample you gathered all attributes into `link` array and with my help you prefixed them all with `http://`. All you need now is to store resulting values back in the corresponding attributes. Can't you handle that yourself? – KL-7 Jul 08 '12 at 15:58