rake dependencies vs requirements - ruby-on-rails-3

I have a rake task db:test:prepare that is meant to clear out the test db before tests are run. It seems that it is magically a dependency of the test, test:units, and test:functionals tasks which are defined as part of some core library.
When I run one of test:units, or test:functionals on its own, db:test:prepare runs first and the tests succeed. But if I run the default test task, the second suite of tests fails because the db wasn't reset in between.
Researching around, I find that rake dependencies will be skipped if they've already run once, so if I have task :a => :pre and task :b => :pre, if I define a third task to run both of those, task :c => [:a, :b], when I call rake c, rake will invoke :pre, :a, :b, and not :pre, :a, :pre, :c
I ultimately got the behavior I wanted by writing a new task:
namespace :test do
task :all do
Rake::Task['test:units'].invoke
Rake::Task['db:test:prepare'].execute
Rake::Task['test:functionals'].invoke
end
end
Is there a better way to do this? Or a way to declare that a dependency is required or somesuch? Rake::Task has a #reenable method, which I had hoped would allow a workaround, like to have the "prepare" task reenable itself at the end of execution so that it would be invoked again when the second task depending on it came around, but it doesn't seem to work that way.

Related

how do i target a seeds.rb in an engine to avoid seeding my entire app?

My project is on Rails 3.2 and refinerycms v 2.0.10
I just generated a new engine and and ran my bundle and rails generate commands, and my migration. Now, per the docs, I need to run db:seed but I don't want to execute a db:seed at the app level because I have several other engines and I don't want to re-seed them.
it is related to this question:
Rails engine / How to use seed?
but the answer there is to run db:seed at the app level.
So how would I say something like rake myNewEngine:db:seed ? I know it can be done but my google fu is apparently too weak to dredge it up.
You can just generate your own rake task. Create a your_engine.rake file and make sure it is loaded in your Rakefile.
namespace :your_engine do
namespace :db do
task :seed do
YourEngine::Engine.load_seed
end
end
end
Edit the YOUR_ENGINE/lib/tasks/YOUR_ENGINE_tasks.rake
namespace :db do
namespace :YOUR_ENGINE do
desc "loads all seeds in db/seeds.rb"
task :seeds => :environment do
YOUR_ENGINE::Engine.load_seed
end
namespace :seed do
Dir[Rails.root.join('YOUR_ENGINE', 'db', 'seeds', '*.rb')].each do |filename|
task_name = File.basename(filename, '.rb')
desc "Seed " task_name ", based on the file with the same name in `db/seeds/*.rb`"
task task_name.to_sym => :environment do
load(filename) if File.exist?(filename)
end
end
end
end
end
then in your main app you can execute your custom seeds commands, executing any seed file individually
$rake -T | grep YOUR_ENGINE
rake db:YOUR_ENGINE:seed:seed1 # Seed seed1, based on the file with the same name in `db/seeds/*.rb`
rake db:YOUR_ENGINE:seeds # loads all seeds in db/seeds.rb

Run a rake task rails

I am trying to get a rake task to run, basically a screen grab and then post the data to a model. I have a task but not sure on how to get it to run
namespace :grab do
task :fixtures => :environment do
MatchFixtures::MatchFixtures.new.perform
end
end
Im way out here but i thought it was
rake namespace:task
but i get
dont know how to build task 'namespace:task'
Where am i going wrong?
You're supposed to substitute your own namespace/tasks in there, so:
rake grab:fixtures

Persisted model via save method does not show up in sqlite3 database. Why?

i am new to RoR and probably miss something out.
Can you give me an idea what is wrong?
TestMethod in Unit Test
test "create" do
prices = [12,14,16]
prices.each {|p|
course = Course.new(:name => "j2ee", :price => p)
course.save!
puts course.persisted?
}
#Course.where({:price => 12...17}).all.each do |c|
Course.find_by_price(12) do |c|
puts c.price
end
end
Commandline Output running the test
Running tests:
true
true
true
12
..
like expected.
But why does't the db table contain rows?
sqlite3 test.sqlite3
sqlite> select count(*) from courses;
0
This is def. the right database. If i work with fixture data it is inserted correctly and is until the next testrun available.
Thankx a lot!
cheers
rob
Your question does not specify what testing framework you are using, but generally speaking, testing frameworks cleanup after themselves, which is the polite thing to do.
You did say that it works with fixtures, so you have nothing to worry about. But if you want to manually verify that persistence is working, open the console and type in your test.
prompt$ rails c
> Course.new(:name => "j2ee", :price => 12).save!
> Course.all
The console prints all courses. Note, if you are using bundler (which you should be), you may need to start the console with "bundle exec rails c".

Rails 3.1, why I get ActiveRecord::UnknownAttributeError: unknown attribute in spec test?

I am trying to create a Student record in a test, like this:
student= Student.create!(:work_phone => "1234567890")
but I get this error:
ActiveRecord::UnknownAttributeError: unknown attribute: work_phone
However, work_phone is defined in the Student model, and migrated.
Here is the Studentmodel:
class Student < ActiveRecord::Base
validates_length_of :work_phone, :is => 10, :message => 'must be 10 digits, excluding special characters such as spaces and dashes. No extension or country code allowed.', :if => Proc.new{|o| !o.work_phone.blank?}
attr_accessible:work_phone
end
Any idea?
Are you getting this error only in your test environment. More specifically, when you run tests using
rake spec
This could be happening becase you have not run your migrations on your test environments.
You can either do,
rake db:migrate RAILS_ENV=test
or after having having run migrations on your development like below.
rake db:migrate
rake db:test:prepare
Only adding attr_accessor:work_phone to model also works.

How to use #valid_attributes in a before block in rails 3 and rspec?

I'm trying different blogs with examples of Rails 3 and RSpec. Yes it's on Windows, so the answer isn't not using Windows. No choice in that. Moving on...
I am able to run the spec either with rspec spec or rake spec:models so that seems fine. However if I try to use a before block with attributes it fails on creating a Person class with those attributes. The other tests are just there to show spec can run.
Made a Person model then updated the spec
\myapp\spec\models\person_spec.rb
require 'spec_helper'
describe Person do
before(:each) do
#valid_attributes = {
:first_name => "Foo",
:last_name => "Bar"
}
end
it "should create a new instance given valid attributes" do
Person.create!(#valid_attributes)
end
it "can be instantiated" do
Person.new.should be_an_instance_of(Person)
end
it "can be saved successfully" do
Person.create.should be_persisted
end
#pending "add some examples to (or delete) #{__FILE__}"
end
Here's the output of rake spec:models command
C:\Users\laptop\Documents\Sites\myapp>rake spec:models
C:/Ruby193/bin/ruby.exe -S rspec ./spec/models/person_spec.rb
Person
←[31m should create a new instance given valid attributes (FAILED - 1)←[0m
←[32m can be instantiated←[0m
←[32m can be saved successfully←[0m
Failures:
1) Person should create a new instance given valid attributes
←[31mFailure/Error:←[0m ←[31mPerson.create!(#valid_attributes)←[0m
←[31mActiveRecord::UnknownAttributeError:←[0m
←[31munknown attribute: first_name←[0m
←[36m # ./spec/models/person_spec.rb:13:in `block (2 levels) in <top (required)>'←[0m
Finished in 0.074 seconds
←[31m3 examples, 1 failure←[0m
Failed examples:
←[31mrspec ./spec/models/person_spec.rb:12←[0m ←[36m# Person should create a new instance given valid attributes←[0m
rake aborted!
C:/Ruby193/bin/ruby.exe -S rspec ./spec/models/person_spec.rb failed
So two out of three passed just not the one with attributes.
Anything in particular that would need to be setup for a before block to run or how are attributes passed in a test with Rails 3?
Also is there a way to get rid of those ]31m and such printouts for each spec line?
Thanks
It would appear from the error that ActiveRecord can't find the attribute :first_name that you are passing as part of #valid_attributes. That is, the problem isn't with how you are using RSpec, but with the attributes you are expecting a valid model to contain.
Check that you have a :first_name field or attribute on the Person model - and verify the exact spelling (:first_name vs :firstname or some other variation)
I should update this with the answer.
The Person model did in fact contain first_name and last_name but as noted by two people above the error I was receiving pointed to ActiveRecord not finding it.
In Windows, running rake db:migrate two or three times eventually fixed it even though it wasn't missing in the model.
If you're stuck on Windows dev, this may be a good thing to know!
I finally was able to put Lubuntu on a VirtualBox on Windows 7 and it ran fine and since then I have proceeded with other examples from there.
Cheers