Question

I have a method in my application that finds a photo from the og:image tag of a link that is submitted. In my create action, I use the method photo_form_url, described below.

def photo_from_url(url)
  if !Nokogiri::HTML(open(url)).css("meta[property='og:image']").blank?
    photo_url = Nokogiri::HTML(open(url)).css("meta[property='og:image']").first.attributes["content"]
    self.photo = URI.parse(photo_url)
    self.save
  end 
end

However, this produces an error if a bad url is entered. I tried to rescue as below, but this gives me an "undefined method redirect_to"

def photo_from_url(url)
  begin
    if !Nokogiri::HTML(open(url)).css("meta[property='og:image']").blank?
      photo_url = Nokogiri::HTML(open(url)).css("meta[property='og:image']").first.attributes["content"]
      self.photo = URI.parse(photo_url)
      self.save
    end
  rescue OpenURI::HTTPError
    redirect_to :back, notice: 'link's broken!'
  end
end

What am I doing wrong?

Was it helpful?

Solution

According to your answer to my comment, your function photo_from_url is defined in the model. Trying to redirect a user within a model is not possible as shown by the error you are facing.

Bear in mind that your model can be called outside of a browsing session environment. EG:

  • tests
  • rake task

You should thus never, ever put any code that has to do with manipulating the user browser, or the user session within your models. This is the job of the controller.

So what you need to do is simply raise an exception or return a specific value in your model when you are encountering a bad url. And react to that exception / return value in your controller by redirecting the user. This ensure that anything that has to do with the user browser stays in the controller, and that you could implement a different behavior in a rake task if encountering the same error.

So, your model should do stuff, and raise errors when it can't :

# Link.rb
def photo_from_url(url)
  if !Nokogiri::HTML(open(url)).css("meta[property='og:image']").blank?
    photo_url = Nokogiri::HTML(open(url)).css("meta[property='og:image']").first.attributes["content"]
    self.photo = URI.parse(photo_url)
    self.save
  end 
end

Your controller should ask your model to do stuff, and deal with the user if there is a problem :

# link_controller
# in create
begin
  link.photo_from_url(url)
rescue OpenURI::HTTPError
   redirect_to :back, notice: 'link's broken!'
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top