problems testing active scaffold with rspec

178 views
Skip to first unread message

Michael Richardson

unread,
Jun 5, 2011, 8:50:54 PM6/5/11
to ActiveScaffold : Ruby on Rails plugin
I've just created a directory of very elementary controllers with AS
to act as admin interface.
My app/controllers/admin/admin_controller.rb:

class Admin::AdminController < ApplicationController
load_and_authorize_resource
before_filter :ensure_admin
layout "administrator"

ActiveScaffold.set_defaults do |config|
config.ignore_columns.add
[:created_at, :updated_at, :lock_version]
end

def ensure_admin
redirect_to root_url unless current_user.admin?
end

def current_ability
@current_ability ||= AdminAbility.new(current_user,
params[:format])
end
end

from admin/users_controller.rb:
class Admin::UsersController < Admin::AdminController
active_scaffold :users do |config|
config.columns.add :password
end
end

(password is a virtual field in devise models).

This works great from a browser. No problems.

require 'spec_helper'

describe Admin::UsersController do
include Devise::TestHelpers
fixtures :users

describe "admin users" do
it "can create new user without password" do
@adminuser= users(:admin)
sign_in(@adminuser)

post :create, :user => {
:email => 'au...@example.com',
:fullname => 'Frank Jones'
}
assert_response 201
end
end
end

This blows up with:

marajade-[~/C/hydra/portal] mcr 10043 %bundle exec rspec spec/
controllers/admin/users_controller_spec.rb
F

Failures:

1) Admin::UsersController admin users can create new user without
password
Failure/Error: post :create, :user => {
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.each
# ./spec/controllers/admin/users_controller_spec.rb:13


Too many layers to debug through, and obviously the error is not at
line 13. Line 13 is just the post :create line.
If I insert my own "def create" method (rather than let AS provide
it), then I have no problems, but of course, then I have have to
generate out everything including the views, etc. which isn't what I
wanted to do...

Even a clue on how to debug this would be great.

Hernan Astudillo

unread,
Jun 6, 2011, 12:35:49 AM6/6/11
to actives...@googlegroups.com


looks like AS can't reach columns array.
Try to logger.info the record object with before_create_save(record)
in your controller to see if AS is getting it and parsing columns.

>
> Too many layers to debug through, and obviously the error is not at
> line 13.  Line 13 is just the post :create line.
> If I insert my own "def create" method (rather than let AS provide
> it), then I have no problems, but of course, then I have have to
> generate out everything including the views, etc. which isn't what I
> wanted to do...
>
> Even a clue on how to debug this would be great.
>


you can get ruby_debug gem. It let's you go through all the whole
process. It's long, but you can see everything AS do (plus all rails
stack). You can pause the process and examine objects, even execute
(tweak) code.

> --
> You received this message because you are subscribed to the Google Groups "ActiveScaffold : Ruby on Rails plugin" group.
> To post to this group, send email to actives...@googlegroups.com.
> To unsubscribe from this group, send email to activescaffol...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/activescaffold?hl=en.
>
>

Michael Richardson

unread,
Jun 7, 2011, 8:48:10 PM6/7/11
to ActiveScaffold : Ruby on Rails plugin
On Jun 6, 12:35 am, Hernan Astudillo <naa...@gmail.com> wrote:
>
> looks like AS can't reach columns array.
> Try to logger.info the record object with before_create_save(record)
> in your controller to see if AS is getting it and parsing columns.

Thanks, I'l try this.

> > Too many layers to debug through, and obviously the error is not at
> > line 13.  Line 13 is just the post :create line.
> > If I insert my own "def create" method (rather than let AS provide
> > it), then I have no problems, but of course, then I have have to
> > generate out everything including the views, etc. which isn't what I
> > wanted to do...
>
> > Even a clue on how to debug this would be great.
>
> you can get ruby_debug gem. It let's you go through all the whole
> process. It's long, but you can see everything AS do (plus all rails
> stack). You can pause the process and examine objects, even execute
> (tweak) code.

I know well how to use ruby-debug. The problem is that there are
multiple places
where send() is used and sometimes eval, and each of those things
makes the traceback stack difficult to follow,
and there are simply too many places where you don't know whether to
step vs next, and you either spend an
hour tracing through code that didn't matter, or you miss the
important part. Binary search would be useful
if you could line up all the code linearly, but it's not written that
way.

I've considered some kind of meta-programming that would print the
name of each function as
it is entered/exited: I imagine it already exists, but I haven't
figured out how to do that. It would be
big and slow, but it would help for situations like this.

Michael Richardson

unread,
Jun 21, 2011, 9:57:08 PM6/21/11
to ActiveScaffold : Ruby on Rails plugin
I have figured out the problem. before_create_save is never called.
I wound up single stepping through way too much code. I wonder if
ruby-debug has some way to put a break point
at the location where an exception is raised?

The problem was in active_scaffold/lib/active_scaffold/
attribute_params.rb, in update_record_from_params.
The "attributes.each" was causing the nil exception. (should it
protect itself?), and this called from
create.db, do_create:

@record = update_record_from_params(new_model,
active_scaffold_config.create.columns, params[:record])

Suddenly, I asked, why is params[:record] nil? Then I asked... why
is the new object expected in params[:record],
rather than params[model.to_s] ?

I can see why AS might want to regularize how things are submitted,
but stock rails scaffold'ed controllers would
have used a params named after the model. I'm sure that this is
documented somewhere, but I certainly missed it.
I adjusted my test case to read:

post :create, :record => {
:email => 'au...@example.com',
:fullname => 'Frank Jones'
}

I also think that AS should return a 201 status code on create, even
if it renders a view in HTML.
Reply all
Reply to author
Forward
0 new messages