Попробуйте сосредоточиться на том, чтобы все работало в первую очередь, прежде чем перемещать его в гем / плагин.
Кроме того, забудьте об интерфейсе / абстрактном классе - просто напишите код, который делает это.
Единственная вещь, которую должна знать ваша модель, - это удаленный рецепт и какой URL.
Вы можете поместить весь код очистки в приложение / скребки. Вот пример схемы реализации:
class RecipePage
def new(url)
@url = url
@parser = get_parser
end
def get_attributes
raise "trying to scrape unknown site" unless @parser
@parser.recipe_attributes(get_html)
end
private
def get_html
#this uses your favorite http library to get html from the @url
end
def get_parser(url)
#this matches url to your class, ie returns domain camelized, or nil if you are not handling particular site yet
return EpicurusComParser
end
end
class EpicurusComParser
def self.recipe_attributes(html)
# this does the hard job of querying html and moving
# all the code to get title, text, image of recipe and return hash
{
:title => "recipe title",
:text => "recipe text",
:image => "recipe_image_url",
}
end
end
тогда в вашей модели
class Recipe
after_create :scrape_recipe, :if => :recipe_url
private
def scrape_recipe
# do that in background - ie in DelayedJob
recipe_page = RecipePage.new(self.recipe_url)
self.update_attributes(recipe_page.get_attributes.merge(:scraped => true))
end
end
Затем вы можете создать больше парсера, т.е. CookComParser и т. Д.