# User.rb model:
before_save :simplify_errors
def simplify_errors
if password_was.blank?
...
end
end
Error
undefined method `was' for nil:NilClass
Rails 3.2.11, Ruby 2.0.0.
Any idea what's happening here?
Related
I have configured Rspec Ruby 2.0.0-p0 and Rails 3.2.14 configuration is perfect I'm sure on that but when I try to run rake spec:controllers it gaves me below error on every request action written in spec example -
*** NoMethodError Exception: undefined method `to_sym' for nil:NilClass
I have written specs for controllers before but never come across such situation, help me If any one has fixed same issue....
Here is my spec and error stack
describe UsersController do
before (:each) do
#user = FactoryGirl.create(:user)
sign_in #user
end
describe "GET 'index'" do
it "should be successful" do
get 'index'
response.should be_success
end
end
describe "GET 'show'" do
it "should be successful" do
get :show, :id => #user.id
response.should be_success
end
it "should find the right user" do
get :show, :id => #user.id
assigns(:user).should == #user
end
end
end
Here is result -
Failures:
1) UsersController GET 'index' should be successful
Failure/Error: get 'index'
NoMethodError:
undefined method `to_sym' for nil:NilClass
# ./spec/controllers/users_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
2) UsersController GET 'show' should be successful
Failure/Error: get :show, :id => #user.id
NoMethodError:
undefined method `to_sym' for nil:NilClass
# ./spec/controllers/users_controller_spec.rb:21:in `block (3 levels) in <top (required)>'
3) UsersController GET 'show' should find the right user
Failure/Error: get :show, :id => #user.id
NoMethodError:
undefined method `to_sym' for nil:NilClass
# ./spec/controllers/users_controller_spec.rb:26:in `block (3 levels) in <top (required)>'
Finished in 0.4741 seconds
3 examples, 3 failures
Failed examples:
rspec ./spec/controllers/users_controller_spec.rb:12 # UsersController GET 'index' should be successful
rspec ./spec/controllers/users_controller_spec.rb:20 # UsersController GET 'show' should be successful
rspec ./spec/controllers/users_controller_spec.rb:25 # UsersController GET 'show' should find the right user
Randomized with seed 19701
My factory is -
FactoryGirl.define do
factory :user do
first_name 'Test User'
last_name 'Last name'
email 'example#example.com'
password 'changeme'
password_confirmation 'changeme'
company 'RR'
confirmed_at Time.now
end
end
We need company name mandatory to create register user.
class UsersController < ApplicationController
before_filter :authenticate_user!
#authorize_resource
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
end
here I have added two methods for test in user controller.
Same thing I tried with demo example that works great but not in my project....
Thanks
If you are using devise gem for authentication then you need to specify the devise mapping in controller test cases.
Replace the code in the before(:each) block with below code
#user = FactoryGirl.create(:user)
#request.env['devise.mapping'] = Devise.mappings[:user]
sign_in #user
Finally I fixed issue, it comes due to authenticate_user! method in application controller which inherits to every controllers -
prepend_before_filter :authenticate_user!, :except => [:not_authenticated]
I have added below module to fix issue occurs due to this devise method -(support/controllers_helpers.rb)
module ControllerHelpers
def sign_in(user = double('user'))
if user.nil?
request.env['warden'].stub(:authenticate!).
and_throw(:warden, {:scope => :user})
controller.stub :current_user => nil
else
request.env['warden'].stub :authenticate! => user
controller.stub :current_user => user
end
end
end
finally include above module in spec_helper.rb file
config.include ControllerHelpers, :type => :controller
Got running all controllers specs.
Cheers!!!
more info
When trying to use a serialized attribute (with a defined class) Rails is happy until after the object is saved. I have validations both in my ActiveRecord model and the serialized object (which uses ActiveModel::Validations). As part of my validations, the parent model checks to make sure the serialized object is valid?. I believe this is the heart of the issue, but I'm (a) not sure why it's causing a problem or (b) the best way to fix it.
I've simplified the problem to a minimal rails project:
Code
Creating a fresh rails project (version 3.2.6) and creating an A model with rails g model a data:text I define:
app/models/a.rb
class A < ActiveRecord::Base
attr_accessible :data
serialize :data, B
validate :custom
def custom
errors.add :data, "whoopsies!" unless data.valid?
end
end
app/models/b.rb
class B
include ActiveModel::Validations
attr_accessor :foo
validates_presence_of :foo
end
test/unit/a_test.rb
require 'test_helper'
class ATest < ActiveSupport::TestCase
test "weird failure" do
a = A.new
b = B.new
b.foo = 'bar'
a.data = b
assert a.valid?
assert b.valid?
assert a.save
assert a.valid? # -> throws exception
end
end
Exception
Running this test throws the following exception:
NoMethodError: undefined method `read_attribute_for_validation' for nil:NilClass
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/errors.rb:254:in `block in add_on_blank'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/errors.rb:253:in `each'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/errors.rb:253:in `add_on_blank'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/validations/presence.rb:8:in `validate'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:310:in `_callback_before_7'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:407:in `_run__2107971919899649095__validate__2662006763039653414__callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:405:in `__run_callback'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:385:in `_run_validate_callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:81:in `run_callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/validations.rb:226:in `run_validations!'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/validations.rb:193:in `valid?'
/Users/gbelote/tmp/serialize-fail/app/models/a.rb:8:in `custom'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:407:in `_run__3204678033069886840__validate__2662006763039653414__callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:405:in `__run_callback'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:385:in `_run_validate_callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:81:in `run_callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/validations.rb:226:in `run_validations!'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/validations/callbacks.rb:53:in `block in run_validations!'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:403:in `_run__3204678033069886840__validation__2662006763039653414__callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:405:in `__run_callback'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:385:in `_run_validation_callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activesupport-3.2.6/lib/active_support/callbacks.rb:81:in `run_callbacks'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/validations/callbacks.rb:53:in `run_validations!'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activemodel-3.2.6/lib/active_model/validations.rb:193:in `valid?'
/Users/gbelote/.rvm/gems/ruby-1.9.2-p290#serialize-fail/gems/activerecord-3.2.6/lib/active_record/validations.rb:69:in `valid?'
/Users/gbelote/tmp/serialize-fail/test/unit/a_test.rb:14:in `block in <class:ATest>'
Another clue
When running puts a.data.inspect I get differing results before and after the a.save:
before: #<B:0x0000010327e710 #foo="bar", #validation_context=nil, #errors=#<ActiveModel::Errors:0x0000010321b7a0 #base=#<B:0x0000010327e710 ...>, #messages={}>>
after: #<B:0x00000103197158 #foo="bar", #validation_context=nil, #errors=#<ActiveModel::Errors:0x000001031965f0 #base=nil, #messages={}>>
So #base within #errors is nil, and that's the nil referred to in the exception undefined methodread_attribute_for_validation' for nil:NilClass`.
Anyone know what's going on? Is this a Rails bug? Am I doing something wrong?
Thanks!
Upgrading to ruby 1.9.3-p194 fixed the issue, I was using 1.9.2-p290 previously. Relevant github issue: https://github.com/rails/rails/issues/6889
I have nested my resources (see below) and when I try to create a new entity, I get the following error. Does anyone know why I'm getting this error and how to solve it?
undefined method `applications' for nil:NilClass
resources careers do
resources applications
end
Within the 'Applications' controller I have:
before_filter [[:authenticate, :except => :new], :load_career]
def create
# The following line is where the error originates
#application = #career.applications.new(params[:application])
respond_to do |format|
...
end
end
private
def load_career
#career = Career.find(params[:career_id])
end
The Career and Application models have has_many :applications and belongs_to :career respectively.
And the '*_create_applications' migration has a career_id field.
I have never seen before_filters defined that way. I just tried it in Rails 3 and it doesn't seem to do anything. I would give each callback it's own before_filter call:
before_filter :authenticate, :except => :new
before_filter :load_career
I am trying to create a mailer class for a RoR webapp I am working on for a class. I followed the rails guides steps online, but when I try to call my ActionMailer I get a NoMethodError: undefined method `mail' for MyMailer:Class.
Here's my code for MyMailer
def MyMailer.immediate_notification_mail(r, st)
#url = "myurl"
st.each do |s|
mail(:to => s.email, :subject => "Subject")
end
end
I call this method from another class with the folowing line of code:
MyMailer.immediate_notification_mail(rp, st).deliver
Can anyone tell me what I might be doing wrong? I haven't seen anyone else with this problem.
Thanks!!
The issue is you are setting up a static (class) method.
def MyMailer.immediate_notification_mail(r, st)
This should be:
def immediate_notification_mail(r, st)
I followed the installation procedure of geokit-rails3, here is my conf :
Using rails (3.0.4)
Using activerecord (3.0.4)
Using geokit (1.5.0)
Using geokit-rails (1.1.4)
I get this error "undefined method `within' for #" when i try to query with the "within" method. (note that i am new to rails and maybe missing something obvious)
Here is my class definition :
class Snip < ActiveRecord::Base
belongs_to :user
acts_as_mappable :default_units => :kms,
:default_formula => :sphere,
:distance_field_name => :distance,
:lat_column_name => :latitude,
:lng_column_name => :longitude
end
In my controller i have :
#userLocation = GeoKit::LatLng.new(params[:lat],params[:lng])
#snips = Snip.within(params[:distance], :origin => #userLocation)
Here is what i added to my gemfile :
gem 'geokit', '>= 1.5.0'
gem 'geokit-rails', '1.1.4'
Do you have any idea why i get this error ?
Thanks in advance,
Vincent.
Your gemfile asks for geokit-rails, that's the Rails 2 version. You need to replace that with geokit-rails3