在我的任务文件post.rake
中,我想重用一个函数
def save_post(title, href, source)
post = Post.new(title: title, url: href, source: source)
if post.save
puts title + 'saved'
else
puts title + 'not saved'
end
end
但是,当我在此文件中定义并重新使用它时,它会返回
NoMethodError: undefined method `save_post' for main:Object
post.rake
看起来像这样:
task :fetch_post => :environment do
require 'nokogiri'
require 'open-uri'
url = 'http://example.com'
doc = Nokogiri::HTML(open(url) )
puts doc.css("title").text
doc.css(".a").each do |item_info|
title = item_info.text
href = item_info['href']
save_post(title, href)
end
def save_post(title, href)
post = Post.new(title: title, url: href)
if post.save
puts title + 'saved'
else
puts title + 'not saved'
end
end
end
内容抓取部分有效。我只是将保存后的代码移出,想要抽象出方法。
我应该在哪里放def method
?
答案 0 :(得分:3)
task :fetch_post => :environment do
require 'nokogiri'
require 'open-uri'
def save_post(title, href)
post = Post.new(title: title, url: href)
if post.save
puts title + 'saved'
else
puts title + 'not saved'
end
end
url = 'http://example.com'
doc = Nokogiri::HTML(open(url) )
puts doc.css("title").text
doc.css(".a").each do |item_info|
title = item_info.text
href = item_info['href']
save_post(title, href)
end
end
答案 1 :(得分:3)
如果您在rake任务中定义方法,则它们可以全局访问,这可能会产生不良副作用。更简洁的方法是使用内联lambda(或将方法移动到应用程序中的某个类)
task :fetch_post => :environment do
require 'nokogiri'
require 'open-uri'
save_post = ->(title, href) {
post = Post.new(title: title, url: href)
if post.save
puts title + 'saved'
else
puts title + 'not saved'
end
}
url = 'http://example.com'
doc = Nokogiri::HTML(open(url) )
puts doc.css("title").text
doc.css(".a").each do |item_info|
title = item_info.text
href = item_info['href']
save_post.call(title, href)
end
end
答案 2 :(得分:2)
您应该在任务之前和之外定义方法:
task :fetch_post => :environment do
require 'nokogiri'
require 'open-uri'
url = 'http://example.com'
doc = Nokogiri::HTML(open(url) )
puts doc.css("title").text
doc.css(".a").each do |item_info|
title = item_info.text
href = item_info['href']
save_post(title, href)
end
end
def save_post(title, href)
post = Post.new(title: title, url: href)
if post.save
puts title + 'saved'
else
puts title + 'not saved'
end
end
但我认为这种逻辑应该在模型中。
#app/models/post.rb
class Post < ActiveRecord::Base
def self.save_post(title, href)
post = Post.new(title: title, url: href)
if post.save
puts title + 'saved'
else
puts title + 'not saved'
end
end
end