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?
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:
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