I'm having a little difficulty groking the call back model and methodology in Factory Girl. Using this post http://robots.thoughtbot.com/post/254496652/aint-no-calla-back-girl I started giving it a go and, now I'm erroring in the spec. I am new to Rails...so I may be missing something really fundamental.
The Error is: Failure/Error: @user = Factory(:admin_user) undefined method 'each' for #
The Models:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable, :lockable and :timeoutable
devise :database_authenticatable, :registerable, :lockable,
:recoverable, :rememberable, :trackable, :validatable, :token_authenticatble
# Setup accessible (or protected) attributes for your model
attr_accessible :username, :email, :role_ids, :password, :password_confirmation, :remember_me
has_many :userroles
has_many :roles, :through=>:userroles
def role?(role)
return !!self.roles.find_by_name(role.to_s.camelize)
end
end
class Role < ActiveRecord::Base
attr_accessible :name
validates :name, :presence=>true,
:length=>{:minimum=>4, :maximum=>30}
has_many :userroles
has_many :users, :through=>:userroles
end
class Userrole < ActiveRecord::Base
attr_accessible :user_id, :role_id
belongs_to :user
belongs_to :role
end
The Factories:
Factory.define :user do |f|
f.email 'someone@somecompany.com'
f.username 'foo'
f.password '123456'
end
Factory.define :role do |r|
r.name 'testrole'
end
Factory.define :userrole do |ur|
ur.association(:role)
ur.userrole{|ur| ur.userrole(:user)}
end
Factory.define :admin_role, :class => 'Role' do |userrole|
userrole.role { |role| role.association(:role, :name => "Admin") }
end
Factory.define :admin_user, :parent => :user do |user|
user.after_create { |u| Factory(:admin_role, :userroles => u) }
end
Lastly the simple spec:
require File.dirname(__FILE__) + '/../spec_helper'
describe RolesController do
fixtures :all
include Devise::TestHelpers
render_views
before (:each) do
@user = Factory(:admin_user)
sign_in @user
end
it "index action should render index template" do
get :index
response.should render_template(:index)
end
end
Update: Adding Stack Trace
ruby-1.9.2-p136 :001 > u=Factory(:admin_user)
NoMethodError: undefined method `each' for #<User:0x00000004d737d8>
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/activemodel-3.0.3/lib/active_model/attribute_methods.rb:364:in `method_missing'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/activerecord-3.0.3/lib/active_record/attribute_methods.rb:46:in `method_missing'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/activerecord-3.0.3/lib/active_record/associations/association_collection.rb:352:in `replace'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/activerecord-3.0.3/lib/active_record/associations.rb:1524:in `block in collection_accessor_methods'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/proxy/build.rb:13:in `set'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/factory.rb:320:in `block in run'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/factory.rb:320:in `each'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/factory.rb:320:in `run'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/factory.rb:270:in `create'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/factory.rb:301:in `default_strategy'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl.rb:20:in `Factory'
from /home/ryan/Sites/Holocron/spec/factories/users.rb:22:in `block (2 levels) in <top (required)>'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/proxy.rb:29:in `call'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/proxy.rb:29:in `block in run_callbacks'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/proxy.rb:28:in `each'
from /home/ry开发者_C百科an/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/proxy.rb:28:in `run_callbacks'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/proxy/create.rb:7:in `result'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/factory.rb:327:in `run'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/factory.rb:270:in `create'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl/factory.rb:301:in `default_strategy'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/factory_girl-1.3.2/lib/factory_girl.rb:20:in `Factory'
from (irb):1
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/railties-3.0.3/lib/rails/commands/console.rb:44:in `start'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/railties-3.0.3/lib/rails/commands/console.rb:8:in `start'
from /home/ryan/.rvm/gems/ruby-1.9.2-p136@Holocron/gems/railties-3.0.3/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
I believe you've confused yourself.
You've defined Factory.define :admin_role, :class => 'Role' do |userrole|
as a Role
but then in your factory definition you treat it like a Userrole
. (BTW, Ruby conventions use underlines – so Userrole would be UserRole/user_role.)
Also, your user.after_create { |u| Factory(:admin_role, :userroles => u) }
probably ought to be: user.after_create { |u| Factory(:admin_role, :userroles => [u]) }
since a Role
has_many :userroles
.
精彩评论