Let's say I have a ruby or json file consisting of hashes and range anywhere from 14-20MB (300K lines unminified). I've created a rake task which loops through each hash and creates an AR object based on the values in each hash.
Unfortunately due to the file's size I get stack level too deep errors each time I run the task. The only way I've actually gotten the script to run is by splitting the file into smaller ones. Although this works, it gets extremely tedious to split the file and repeat the task over and over. Are there any good alternatives for loading/running large files?
Rake Task
namespace :db do
task populate: :environment do
$restaurants.each_with_index do |r, index|
uri = URI(r[:website])
restaurant = Restaurant.find_or_create_by(name: r[:name], website: "#{uri.scheme}://#{uri.host}")
restaurant.cuisines = r[:cuisines].map { |c| Cuisine.find_or_create_by(name: c) }
location = Location.create(
restaurant: restaurant,
city_id: 1,
address: r[:address],
latitude: r[:latitude],
longitude: r[:longitude],
phone_number: r[:phone_number]
)
r[:hours].each do |h|
Hour.create(
location: location,
day: Date::DAYNAMES.index(h[:day]),
opens: h[:opens],
closes: h[:closes]
)
end
menu_group = MenuGroup.create(
restaurant: restaurant,
locations: [location],
address: r[:address]
)
r[:menus].each do |m|
menu = Menu.create(
menu_group: menu_group,
position: m[:position],
name: m[:name]
)
m[:sections].each do |s|
section = Section.create(
menu: menu,
position: s[:position],
name: s[:name]
)
s[:dishes].each do |d|
tag = Tag.find_or_create_by(
name: d[:name].downcase.strip
)
Dish.find_or_create_by(
restaurant: restaurant,
sections: [section],
tags: [tag],
name: d[:name],
description: d[:description]
)
end
end
end
puts "#{index + 1} of #{$restaurants.size} completed"
end
end
end
Error
rake aborted!
SystemStackError: stack level too deep
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/compile_cache/iseq.rb:12:in`to_binary'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/compile_cache/iseq.rb:12:in`input_to_storage'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/compile_cache/iseq.rb:37:in`fetch'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/compile_cache/iseq.rb:37:in`load_iseq'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `block in require_with_bootsnap_lfi'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:65:in `register'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:20:in `require_with_bootsnap_lfi'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:29:in `require'
/usr/local/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `block in require'
/usr/local/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:249:in `load_dependency'
/usr/local/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `require'
/Users/user/app/lib/tasks/populate.rake:1:in `<main>'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:50:in `load'
/usr/local/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:50:in `load'
/usr/local/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:277:in `block in load'
/usr/local/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:249:in `load_dependency'
/usr/local/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:277:in `load'
/usr/local/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:650:in `block in run_tasks_blocks'
/usr/local/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:650:in `each'
/usr/local/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:650:in `run_tasks_blocks'
/usr/local/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/application.rb:515:in `run_tasks_blocks'
/usr/local/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:459:in `load_tasks'
/Users/user/app/Rakefile:6:in `<top (required)>'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.1/exe/rake:27:in `<top (required)>'
(See full trace by running task with --trace)
I would use something like Sidekiq to break the jobs in to workers that can run concurrently.
For example:
$restaurants.each_with_index do |r, index|
RestaurantParser.perform_async(r, index)
end
In RestaurantParser perform the steps you would normally take.
As long as restaurants don't rely on other restaurants already existing in the DB you can run workers concurrently to speed up the process.
Related
I am trying to test my application and I continually get the following error:
Error:
ContractsControllerTest#test_should_get_show:
ActiveRecord::Fixture::FormatError: ActiveRecord::Fixture::FormatError
Error:
ContractsControllerTest#test_should_get_show:
NoMethodError: undefined method `each' for nil:NilClass
Below is the code on my contract controller and I have similar code like this on all the controllers.
def index
#contract = Contract.all.paginate(page: params[:page], :per_page => 70)
end
def show
#contract = Contract.find(params[:id])
end
def new
#contract = Contract.new
end
def create
#contract = Contract.new(located)
if #contract.save
flash[:success] = "A record has been successfully added"
redirect_to contracts_path
else
render 'new'
end
end
def located
params.require(:contract).permit(:contract_name, :contract_status, :services_rendered, :contract_value, :award_year)
end
# editing a record in the contract from cotract table
def edit
#contract = Contract.find(params[:id])
end
def update
#contract = Contract.find(params[:id])
if #contract.update_attributes(located)
flash[:success] = "Contract form updated"
redirect_to contracts_path
else
render'edit'
end
end
def destroy
Contract.find(params[:id]).destroy
flash[:success] = "A record has been successfully deleted"
redirect_to contracts_path
end
Below is the full trace of the error when I run the command rails db:fixtures:load --trace
rails aborted!
ActiveRecord::Fixture::FormatError: ActiveRecord::Fixture::FormatError
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixture_set/file.rb:72:in `validate'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixture_set/file.rb:49:in `raw_rows'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixture_set/file.rb:37:in `config_row'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixture_set/file.rb:27:in `model_class'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:791:in `block (2 levels) in
read_fixture_files'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixture_set/file.rb:15:in `open'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:790:in `block in read_fixture_files'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:789:in `each'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:789:in `each_with_object'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:789:in `read_fixture_files'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:598:in `initialize'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:529:in `new'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:529:in `block (2 levels) in
create_fixtures'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:526:in `map'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:526:in `block in create_fixtures'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/connection_adapters/postgresql/referential_integrity.rb: 22:in `disable_referential_integrity'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/fixtures.rb:523:in `create_fixtures'
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-
5.0.5/lib/active_record/railties/databases.rake:207:in `block (3 levels) in
<top (required)>'
/usr/local/rvm/gems/ruby-2.3.0/gems/railties-
5.0.5/lib/rails/commands/rake_proxy.rb:14:in `block in run_rake_task'
/usr/local/rvm/gems/ruby-2.3.0/gems/railties-
5.0.5/lib/rails/commands/rake_proxy.rb:11:in `run_rake_task'
/usr/local/rvm/gems/ruby-2.3.0/gems/railties-
5.0.5/lib/rails/commands/commands_tasks.rb:51:in `run_command!'
/usr/local/rvm/gems/ruby-2.3.0/gems/railties-
5.0.5/lib/rails/commands.rb:18:in `<top (required)>'
/home/ubuntu/workspace/final_project/bin/rails:9:in `require'
/home/ubuntu/workspace/final_project/bin/rails:9:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-
2.0.2/lib/spring/client/rails.rb:28:in `load'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-
2.0.2/lib/spring/client/rails.rb:28:in `call'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-
2.0.2/lib/spring/client/command.rb:7:in `call'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-2.0.2/lib/spring/client.rb:30:in
`run'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-2.0.2/bin/spring:49:in `<top
(required)>'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-
2.0.2/lib/spring/binstub.rb:31:in `load'
/usr/local/rvm/gems/ruby-2.3.0/gems/spring-
2.0.2/lib/spring/binstub.rb:31:in`<top (required)>'
/home/ubuntu/workspace/final_project/bin/spring:15:in `require'
/home/ubuntu/workspace/final_project/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:fixtures:load
(See full trace by running task with --trace)
My application containts 12 controllers, the same error occurs in each of the controllers. Also, I have 10 tables in my schema some of which contain references / relations to each other.
I don't really know what is wrong and I have be struggling with this problem for about four days now. I would be grateful if anyone could help me with any code or information that could help me to trace the source of the error. I would also be grateful if you could provide information for exactly where I should place the code to trace and solve this error.
Thanks
One of your fixture files in test/fixtures has bad formatting. The problem does not appear to be with your controllers or tests since it is happening for every single one of them. All of the fixtures get loaded into the test database before every single test, even if some are not used for the current test. So if there is an error in one of these files it will get raised for every test.
According to the line from the activerecord source that is throwing the error at the top of the stack trace you've provided, ActiveRecord is expecting every entry in your YAML fixture file to be a key which references a hash.
Each entry in a fixture should represent a model instance. The top level key is used as a name to reference that instance (rails usually names them one and two when generating the fixture template for a new model). Here is an example YAML fixture with one good entry and a few different types of bad ones.
# This will produce a hash associated to key :hash_entry.
# This is the correct type of entry, all others that follow are incorrect for rails fixtures.
hash_entry:
key1: value1
key2: value2
# This will produce the string "not a hash" associated to key :string_entry
string_entry: not a hash
# This will produce the array ["also", "not","a","hash"] associated to key :array_entry
array_entry:
- also
- not
- a
- hash
# This will produce nil associated to key :nil_entry
nil_entry:
You need to examine your fixtures files in test/fixtures and look for any that have the bad formatting as described above. Here is a rake task that will help you identify which files and entries need to be corrected. First run rails g task fixtures check_format, and place this code inside of the rake file that gets generated at lib/tasks/fixtures.rake.
namespace :fixtures do
desc "Looks for bad fixture files"
task check_format: :environment do
fixtures_dir = Rails.root.join("test", "fixtures")
fixture_files = Pathname.glob("#{fixtures_dir}/**/*.yml")
fixture_files.each do |file|
fixture = YAML.load(IO.read(file))
fixture.each_pair do |name, entry|
puts "Bad fixture entry #{name}: #{entry.inspect} in fixture #{file}" unless entry.is_a? Hash
end
end
end
end
Then run rails fixtures:check_format and the offending files and entries will be printed out on the command line for you to find and correct.
I've been tasked with adding seeds to an existing Rails project. I've been given a list of twelve survey names and I'm supposed to create them all, storing their id (position in the list of surveys) and name values, then loop over them and add a placeholder survey_question to each. I know how to do it if I were to create a new migration, redefining survey_question as an attribute of survey, but I'm supposed to work with the existing structure where survey and survey_question are distinct classes. And I've hit a wall.
My thinking was to put all the survey names in an array, thus ordering them automatically when the database is seeded:
surveys = [
"SurveyA",
"SurveyB",
"SurveyC",
"SurveyD",
"SurveyE",
"SurveyF",
"SurveyG",
"SurveyH",
"SurveyI",
"SurveyJ",
"SurveyK",
"SurveyL"
]
Then write an each loop that instantiates the Survey class and stores the given name as the name attribute of the database entry. Within that same loop I define survey_question as a placeholder question (which some of you may recognize), and attempt to append it to the Survey being created with the << operator. This is my first point of failure:
surveys.each do |survey|
survey_question = SurveyQuestion.create(body: "What is the average flight speed velocity of an unladen swallow?")
Survey.create(name: survey) << survey_question
end
Great, I've written a loop. I need to verify that it does what I want it to do. So I go to re-seed the database and run rake db:seed. When I do, however, I get a validation error from a line in the seeds.rb file that came with the project. See here:
rake aborted!
undefined method `<<' for #<Survey:0x007fb01fe1a3d0>
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activemodel-4.0.3/lib/active_model/attribute_methods.rb:439:in `method_missing'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/attribute_methods.rb:155:in `method_missing'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:95:in `block in <top (required)>'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:93:in `each'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:93:in `<top (required)>'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `block in load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:214:in `load_dependency'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/railties-4.0.3/lib/rails/engine.rb:540:in `load_seed'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/tasks/database_tasks.rb:154:in `load_seed'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/railties/databases.rake:181:in `block (2 levels) in <top (required)>'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/railties/databases.rake:140:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:setup => db:seed
Here is the offending line (25) from the seeds:
#create seed region
usa = Region.create!(name: "USA")
So I thought, maybe for some wierd reason this was written when the database was created and cannot be overwritten, so if I clear out the database and start anew, it will populate without complaining. I ran rake db:reset. Wrong. At this point I realized there was an error in the way I'd written my each loop above. The error message told me that << is an undefined method for the survey object it was attached to. Here's that messsage.
rake aborted!
undefined method `<<' for #<Survey:0x007fb01fe1a3d0>
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activemodel-4.0.3/lib/active_model/attribute_methods.rb:439:in `method_missing'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/attribute_methods.rb:155:in `method_missing'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:95:in `block in <top (required)>'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:93:in `each'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:93:in `<top (required)>'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `block in load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:214:in `load_dependency'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/railties-4.0.3/lib/rails/engine.rb:540:in `load_seed'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/tasks/database_tasks.rb:154:in `load_seed'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/railties/databases.rake:181:in `block (2 levels) in <top (required)>'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/railties/databases.rake:140:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:setup => db:seed
As a final point of data I checked out what was actually in the database, just to see what was there. This is the result of SELECT * FROM "regions";:
erp_development=# SELECT * FROM "regions"
erp_development-# ;
id | name | created_at | updated_at | default_email_sig
----+------+----------------------------+----------------------------+-------------------
1 | USA | 2014-08-01 17:13:06.733146 | 2014-08-01 17:13:06.733146 |
(1 row)
So now I'm good and stuck. I've been learning as much as I can but my understanding of Ruby and Ruby on Rails is entry-level at best. If anyone out there in Stack-land can help shed some light on this for me I will forever be in your debt.
Thanks,
Brian
<< is Ruby Array method. Survey.create(name: survey) won't return you array, so this is the reason why it fails.
According to the documentation .create method returns the resulting object instead! http://apidock.com/rails/ActiveRecord/Base/create/class
survey = Survey.create(name: survey)
survey.survey_questions << question
The code above should work!
The << method just modifies the returning value of survey.survey_questions, it does not modify the object itself. You should use modifying methods like = or +=. Anyway, I think this is a cleaner way to do the same:
surveys.map do |survey|
Survey.create! do |s|
s.name = survey
s.survey_questions.build(body: "What is the average flight speed velocity of an unladen swallow?")
end
end
For now I have:
desc "Index Elastic Search"
namespace :tire do
namespace :import do
task all: :environment do
aliases = Tire::Configuration.client.get(Tire::Configuration.url + '/_aliases').body
indexes_names = MultiJson.load(aliases).keys
indexes_names.each do |name|
index = Tire::Index.new name
index.delete
index.import
index.refresh
puts "[INFO] #{name} re-indexed"
end
end
end
end
But I get an error
wrong number of arguments (0 for 1)
/Users/rege/.rvm/gems/ruby-1.9.3-p194#network/gems/tire-0.5.2/lib/tire/index.rb:185:in `import'
/Users/rege/Code/Network/lib/tasks/tire.rake:15:in `block (4 levels) in <top (required)>'
/Users/rege/Code/Network/lib/tasks/tire.rake:12:in `each'
/Users/rege/Code/Network/lib/tasks/tire.rake:12:in `block (3 levels) in <top (required)>'
Tasks: TOP => tire:import:all
You need to tell each index what to import. Assuming you use the default index naming convention, then you need to do this:
index.import name.singularize.camelcase.constantize.all
UPDATE:
Given your naming style, you can use this:
index.import name.gsub(/^myapp_(development|production)__/, '').singularize.camelcase.constantize.all
I'm a newbie in ruby/rails, currently doing the railstutorial book as a part of a university course.
I'm using ubuntu 11.04, ruby 1.9.2p290, and Rails 3.0.9, watchr (0.7), rspec (2.6.0), rspec-formatter-webkit (2.1.3) and spork (0.9.0.rc).
On github I came across this gem, and I thought it would be very nice to use it.
So basically what I'm trying to achieve is
continuous automated testing with notifications if finished, and also to generate the nice html output out of it.
So what I tried is that I wrote this watchr script:
require 'nokogiri'
require 'open-uri'
watch("spec/.*/*_spec.rb") do |match|
run_spec match[0]
end
watch("app/(.*/.*).rb") do |match|
run_spec %{spec/#{match[1]}_spec.rb}
end
def run_spec(file)
unless File.exist?(file)
puts "#{file} does not exist"
return
end
puts "Running #{file}"
result = `rspec -r rspec/core/formatters/webkit -f RSpec::Core::Formatters::WebKit #{file}`
File.open('out.html', 'w') do |f|
f.puts result
end
notify(result)
puts "DONE"
end
def send_notify title, msg, img, pri='low', time=5000
`notify-send -i #{img} -u #{pri} -t #{time} '#{msg}'`
end
def notify(result)
output = result
doc = Nokogiri::HTML(result)
doc.xpath('//div[#id = "summary"]').each do |node|
output = node.text.split.join(" ")
end
folder = "~/Pictures/autotest/"
if output =~ /([123456789]|[\d]{2,})\sfailed/
send_notify "FAIL:", "#{output}", folder+"rails_fail.png", 'critical', 20000
elsif output =~ /[1-9]\d*\spending?/
send_notify "PENDING:", "#{output}", folder+"rails_pending.png", 'normal', 15000
else
send_notify "PASS:", "#{output}", folder+"rails_ok.png"
end
end
handling the notifications, and generating the output while testing.
If I run this with watchr, everything is nice and working, however the tests are taking a long time of course.
The problem comes in here: if I try to use spork, to speed the tests up, I get a bunch of errors, starting with a LoadError:
Exception encountered: #<LoadError: no such file to load -- rspec/core/formatters/webkit>
backtrace:
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.0.9/lib/active_support/dependencies.rb:239:in `require'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.0.9/lib/active_support/dependencies.rb:239:in `block in require'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.0.9/lib/active_support/dependencies.rb:225:in `block in load_dependency'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.0.9/lib/active_support/dependencies.rb:596:in `new_constants_in'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.0.9/lib/active_support/dependencies.rb:225:in `load_dependency'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.0.9/lib/active_support/dependencies.rb:239:in `require'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:247:in `block in requires='
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:247:in `map'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:247:in `requires='
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/rspec-core-2.6.4/lib/rspec/core/configuration_options.rb:21:in `block in configure'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/rspec-core-2.6.4/lib/rspec/core/configuration_options.rb:20:in `each'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/rspec-core-2.6.4/lib/rspec/core/configuration_options.rb:20:in `configure'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:17:in `run'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/rspec-core-2.6.4/lib/rspec/monkey/spork/test_framework/rspec.rb:5:in `run_tests'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/spork-0.9.0.rc/lib/spork/run_strategy/forking.rb:13:in `block in run'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/spork-0.9.0.rc/lib/spork/forker.rb:21:in `block in initialize'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/spork-0.9.0.rc/lib/spork/forker.rb:18:in `fork'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/spork-0.9.0.rc/lib/spork/forker.rb:18:in `initialize'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/spork-0.9.0.rc/lib/spork/run_strategy/forking.rb:9:in `new'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/spork-0.9.0.rc/lib/spork/run_strategy/forking.rb:9:in `run'
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/spork-0.9.0.rc/lib/spork/server.rb:47:in `run'
/usr/local/ruby/lib/ruby/1.9.1/drb/drb.rb:1558:in `perform_without_block'
/usr/local/ruby/lib/ruby/1.9.1/drb/drb.rb:1518:in `perform'
/usr/local/ruby/lib/ruby/1.9.1/drb/drb.rb:1592:in `block (2 levels) in main_loop'
/usr/local/ruby/lib/ruby/1.9.1/drb/drb.rb:1588:in `loop'
/usr/local/ruby/lib/ruby/1.9.1/drb/drb.rb:1588:in `block in main_loop'
which of course don't really say anything to me, being a total newbie.
Is there a way to overcome this (or of course produce result in any other way)?
Any help is greatly appreciated :)
You might have more luck running the RSpec runner directly rather than shelling out, e.g.,
require 'rspec/core'
require 'rspec/core/formatters/webkit'
# ...then in #run_spec
puts "Running #{file}"
File.open( 'out.html', 'w' ) do |f|
argv = [ '-f', 'RSpec::Core::Formatters::WebKit', file ]
RSpec::Core::Runner.run( argv, f )
end
notify(result)
puts "DONE"
The ActiveSupport monkey(freedom)-patched 'Kernel.require' seems to be the thing that's different in the three scenarios you mentioned.
If you figure out why ActiveSupport can't find the library, I'd be happy to try to work around it in the WebKit formatter.
factory_girl is not recognizing a model name that I've defined, and which I need to reference because I need a subclass. This worked in rails 2 but I'm migrating to rails 3.
Factory definition:
Factory.define :interest, :class => Term::Interest do |f|
f.name {"#{Factory.next(:lipsum_word)}ing"}
end
Definition of Term and Term::Interest
class Term < ActiveRecord::Base
belongs_to :category
class Interest < Term
end
class Award < Term
end
end
Error and stack trace:
$ rake db:data:load --trace
(in /Users/glurban/code/recruitd)
rake aborted!
uninitialized constant Term
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rspec-core-2.4.0/lib/rspec/core/backward_compatibility.rb:20:in `const_missing'
/Users/glurban/code/recruitd/test/factories/factories.rb:316:in `<top (required)>'
/Users/glurban/code/recruitd/lib/tasks/use_factories.rake:2:in `<top (required)>'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/railties-3.0.0/lib/rails/engine.rb:131:in `block in load_tasks'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/railties-3.0.0/lib/rails/engine.rb:131:in `each'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/railties-3.0.0/lib/rails/engine.rb:131:in `load_tasks'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/railties-3.0.0/lib/rails/application.rb:141:in `load_tasks'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/railties-3.0.0/lib/rails/application.rb:77:in `method_missing'
/Users/glurban/code/recruitd/Rakefile:7:in `<top (required)>'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/lib/rake.rb:2383:in `load'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/lib/rake.rb:2383:in `raw_load_rakefile'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/lib/rake.rb:2017:in `block in load_rakefile'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/lib/rake.rb:2016:in `load_rakefile'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/lib/rake.rb:2000:in `block in run'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/gems/rake-0.8.7/bin/rake:31:in `<top (required)>'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/bin/rake:19:in `load'
/Users/glurban/.rvm/gems/ruby-1.9.2-rc2/bin/rake:19:in `<main>'
I tried adding require_dependency 'term' to the top of factories.rb but then I get
Glens-MacBook-Pro:test glurban$ rake db:data:load
(in /Users/glurban/code/recruitd)
rake aborted!
No such file to load -- term
What to do?
Edit: in response to the comment, yes, it happens only on rake, not in the console:
$ rails c
Loading development environment (Rails 3.0.0)
ruby-1.9.2-rc2 > Factory(:term)
=> #<Term id: 3, type: nil, name: "Proud to be a Recruitd user", location: nil, category_id: nil, description: nil, url: nil, created_at: "2011-01-06 21:30:14", updated_at: "2011-01-06 21:30:14">
ruby-1.9.2-rc2 > Factory(:interest)
=> #<Term::Interest id: 4, type: "Term::Interest", name: "siting", location: nil, category_id: nil, description: nil, url: nil, created_at: "2011-01-06 21:30:18", updated_at: "2011-01-06 21:30:18">
Custom rake task definition:
require 'factory_girl'
require File.expand_path("test/factories/factories.rb")
namespace :db do
namespace :data do
desc "Load sample data"
task :load => :environment do |t|
create_students
...
create_student_files_and_feeds
puts "Completed loading sample data."
end
end
end
def create_interests
data_fetch("interests").each do |input|
Factory(:interest, :name => input.strip)
end
puts "Created interests"
end
After looking over the factory_girl documentation again, I realized that you can specify a class using either a string or a class constant. So I tried using a string and it worked:
Factory.define :interest, :class => "Term::Interest" do |f|
f.name {"#{Factory.next(:lipsum_word)}ing"}
end
Also, a comment about the nested classes. I initially did that to keep the classes a little more organized, but given the complexity it's created (especially for routing), I'm just going to move each subclass to its own model file. (If I were to un-nest them without putting them in separate files, rails seems to fail to find the subclasses sometimes--namely if the parent class hadn't been referenced (forcing the load of that file) before.