Filed in
rails |
13 October, 2007
Curiously adding config.log_level = :debug to environment.rb appears to have no effect on the logging performed by ActiveRecord. To get to see the detailed logging and benchmarking of your database queries in production mode you need to place this after the Rails::Initializer.run block in environment.rb:
ActiveRecord::Base.logger.level = Logger::DEBUG
Filed in
rails |
9 October, 2007
Gotcha 1
Failing tests. We’d like them to pass of course. But there is something strange going on - the error is not a test error, it seems to come from rails itself:
1) Error:
test_searcher_email(OrderMailerTest):
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.4/lib/active_record/fixtures.rb:498:in `orders'
./test/unit/order_mailer_test.rb:22:in `test_searcher_email'
1 tests, 0 assertions, 0 failures, 1 errors
What does it mean? The clue here is that the error comes from fixtures.rb. The other thing to note is that I have a setup in my test:
def setup
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
...
end
Which should be fine, but there is this nasty error. Let’s try something in the setup method - we’ll add a call to super there:
def setup
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
...
super
end
And the result:
Started
.
Finished in 0.160284 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
Great, that’s fixed it. But why? Well it took me a while to find it. Have a look in /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.4/lib/active_record/fixtures.rb - there is your culprit at line 554:
alias_method :setup, :setup_with_fixtures
So the rule is, if you override setup you need to call super otherwise you don’t get your fixtures set up properly.
Gotcha 2
Ever tried to test your routes? You should. But if you have routes that depend on what’s in your database you’ve got a problem. Why? Because the routing is initialised before any fixtures are loaded. In fact none of the test related code is loaded at that point. So your tests just won’t work.
I don’t know a good way to fix this. In the end I opted for a fudge at the beginning of routes.rb:
if ENV['RAILS_ENV'] == "test" && Category.count == 0
Category.create!(:name=>"Families and Friends", :alternative_name=>"Family")
end
And I have a fixture that contains the same information. This isn’t really DRY, but I don’t really see a good way to do this. Maybe we could read the fixtures file ourselves and get the data from there.
But at least the tests run ok now.
Filed in
rails |
28 September, 2007
This is with a brand new installation of ruby (./configure, make, make install) and of rubygems (ruby setup.rb). Odd error message to get really, rails is certainly there .
This helps, but actually all I needed to do was to simply say
gem update
… and then …
gem install rails --include-dependencies
…works as it should.
Filed in
rails |
9 August, 2007
The form_tag method in ActionView uses a nice trick to wrap a block of content in form tags, and you can wrap content the same way yourself.
You want to write something like:
<% yellow_boxed do %>
some text and html and stuff
it's probably only worth doing it this way
if this bit is longer than a line or two
<% end %>
This reads in a very natural way. To do this, I have a helper method called yellow_boxed:
def yellow_boxed(&block)
concat(render(:partial=>"yellow_boxtop"), block.binding)
content = capture(&block)
concat(content, block.binding)
concat(render(:partial=>"yellow_boxbottom"), block.binding)
end
This technique can be used in any situation where it is logical to wrap content.
Note that I render a partial for the top and the bottom of my yellow box. The partials just contain table, tr and td tags and so on, but I wanted to keep the html strings out of my helper. But for short lengths of html it’s not a problem, you can put text strings there instead of the much more expensive calls to render.