johnreilly

www.flickr.com
john.reilly's items Go to john.reilly's photostream

Posts tagged "rails"

subqueries: sqlite3 vs. mysql

Ugh. I thought rails was supposed to handle database peculiarities for me. Is this a bug, or am I being stupid?

Here’s the gist:

tagged as: rails sqlite mysql
Comments (View)

rspec is mocking me

Grr. I hate situations where it works here, but doesn’t work there, and I can’t see where the difference is. Something has to be different, I just can’t for the life of me figure out what. Maybe someone can help.

Here’s what’s up.

I’ve got rspec and rspec-rails installed as git submodules. Running the latest edge rails. I’m gonna generate up a quick rspec_scaffold:

$ script/generate rspec_scaffold Bike name:string sku:string

This generates the following controller test (abridged):


describe BikesController do

  def mock_bike(stubs={})
    @mock_bike ||= mock_model(Bike, stubs)
  end
  
  describe "responding to GET index" do

    it "should expose all bikes as @bikes" do
      Bike.should_receive(:find).with(:all).and_return([mock_bike])
      get :index
      assigns[:bikes].should == [mock_bike]
    end

  end
end

Looks fine. BUT. In my project, this spec fails, because it is somehow loading up the view and the name and sku calls are tripping up the mock, as it isn’t expecting them to be called in this controller test.

Note, however, that I am NOT calling integrate_views inside my controller spec, so I don’t have any idea why the view code is being run.

% rake spec:controllers
(snip)
ActionView::TemplateError in 'BikesController responding to GET index should expose all bikes as @bikes'
Mock 'Bike_1017' received unexpected message :name with (no args)
On line #11 of app/views/index.html.erb

8: 
9: <% for bike in @bikes %>
10:   <tr>
11:     <td><%=h bike.name %></td>
12:     <td><%=h bike.model %></td>
13:     <td><%= link_to 'Show', bike %></td>
14:     <td><%= link_to 'Edit', edit_bike_path(bike) %></td>

app/views/bikes/index.html.erb:11
app/views/bikes/index.html.erb:9:in `each'
app/views/bikes/index.html.erb:9

This happens for 10 of the 18 scaffolded specs.

I can fix the errors by adding expectations to the mock like so:


it "should expose all bikes as @bikes" do
  Bike.should_receive(:find).with(:all).and_return([mock_bike])
  mock_bike.should_receive(:name)      
  mock_bike.should_receive(:sku)
     
  get :index
  assigns[:bikes].should == [mock_bike]
end

But that kind of defeats the purpose of having a controller-only test, as it’s now testing the view code as well.

What’s weird is, I started a brand new project, and all the tests passed with flying colors!

% rails rspectest
% cd rspectest 
% rake db:create:all
% script/plugin install git://github.com/dchelimsky/rspec.git
% script/plugin install git://github.com/dchelimsky/rspec-rails.git
% script/generate rspec
% script/generate rspec_scaffold Bike name:string sku:string  
% rake db:migrate
% rake spec
(in /Users/john/src/test/rspectest)
.....................................

Finished in 1.006109 seconds

37 examples, 0 failures

So a brand new project runs the rspec_scaffold specs in isolation, but my project somehow doesn’t.

I’m tearing my hair out on this one. I can’t figure out what I’ve done to my project to cause these specs to stop working.

Anyone out there have any ideas/suggestions?

Update!

Wow. Through the magic of git bisect, I’ve determined that the problem occurs because of a change in edge rails. Turns out, this commit causes the specs to fail. Everything before it passes, everything after fails.

I have no idea how to fix this (or if it is rails’ or rspec’s fault), but I’m getting closer. :-)

PS, if you’ve never used git bisect before, you really haven’t lived.

Update 2!

The latest commits to rspec and rspec-rails fix the problem. Bravo rspec team.

Comments (View)
Rails people have to be the epitome of cool nerds, with their special lingo and their whiskey drinking from @defunkt, quoting Penny
tagged as: quotes rails
Comments (View)

strange activerecord error

So I’m using the ActiveRecord gem (outside of rails) to translate some data from our old forum database to YAML, so it can be imported into a different system.  But I’m getting an error on one of my models that I just can’t figure out.  Here are the details:

class Topic < ActiveRecord::Base
  set_table_name  "forum_topics"
  set_primary_key "TOPIC_ID"
  
  has_many    :replies, :foreign_key => "TOPIC_ID"
  belongs_to  :forum,   :foreign_key => "FORUM_ID"
  belongs_to  :member,  :foreign_key => "T_AUTHOR"
end

class Reply < ActiveRecord::Base
  set_table_name  "forum_replies"
  set_primary_key "REPLY_ID"
  
  belongs_to :member, :foreign_key => "R_AUTHOR"
  belongs_to :topic,  :foreign_key => "TOPIC_ID"
  belongs_to :forum,  :foreign_key => "FORUM_ID"
end

So, we’ve got two models, Topic and Reply (well, there are more, but they aren’t interesting to the discussion here). The associations are as you’d expect, and I’m telling AR about the legacy DB’s schema.

Everything you’d expect to work with Topics does indeed work:

>> Topic.count 
=> 828
>> Topic.first.T_SUBJECT
=> "Rave Review"

But Replies are screwy for some reason. The associations all work, but trying to get a field’s value barfs out. Example:

>> Reply.count 
=> 2278
>> Reply.first.topic.T_SUBJECT 
=> "Rave Review"
>> Reply.first.R_DATE
ArgumentError: wrong number of arguments (1 for 0)
    from (irb):374:in `method_missing`
    from (irb):374
    from :0
>> Reply.first['R_DATE']
=> "20041206085839"

I’m at a loss. Why can’t I get values from Replies? Topics work fine. For the moment, I’m using the Reply.first['R_DATE'] syntax, but I’d rather not.  Anyone out there have any ideas?

Comments (View)