I am working on the Rails 3 Test cases . While writing case i got Deprecation error like
DEPRECATION WARNING: Errors#on have been deprecated, use Errors#[] instead.
Also note that the behaviour of Errors#[] has changed. Errors#[] now always returns an Array. An empty Array is returned when there are no errors on the specified attribute. (called from on at /usr/local/lib/ruby/gems/1.9.1/gems/activemodel-3.0.0.rc/lib/active_model/deprecated_error_methods.rb:7)
For that i used errors[:field] instead of errors.on(:field)
Now Deprecation error is gone , but cases are not working as earlier it was working . It is not testing any validation for the model
Sol
Replace:
errors.on(:field)
with:
errors.include?(:field)
After searching for examples of how to do this without finding anything I ended up doing:
errors[:field].present? / errors[:field].blank?
Don't know if this is the preferred way but it seems to do the job.
I am using something like this at the moment:
#hamburger.errors[:ingredients].count.should == 1
#hamburger.errors[:ingredients].should include "Tomatoes are missing dude!"
Hope it helps someone, right now it is the cleanest solution for me.
I'm converting my old specs to something like this to remove the deprecation warnings:
model.should have(1).error_on(:field)
model.should have(:no).errors_on(:field)
Related
I came across some horrible looking RSpec 2 test:
something.should be
Nope, I didn't accidentally forget to cut+paste the rest of the line,
that's it!
So what's the exact semantic of that? should_not be_nil ?
Please chime in why this is horrible style.
IMHO it's sloppy, not precise, and does not clearly communicate what's required. (it triggers my gag reflex ;)
You're correct - according to the docs object.should.be equals object.should_not be_nil
Documentation, 4th one down in that first list.
From the docs: "We recommend you use the expect syntax unless you have a specific reason you prefer the should syntax. We have no plans to ever completely remove the should syntax but starting
in RSpec 3, a deprecation warning will be issued if you do not explicitly enable it, with the plan to disable it by default in RSpec 4 (and potentially move it into an external gem)."
I believe the equivalent in newer syntax would be:
expect(something).to be
or more commonly:
expect(something).not_to be_false
My Rails 4/Ruby 2 app is throwing the following warning every time my RSpec tests create a FactoryGirl object: "DEPRECATION WARNING: This dynamic method is deprecated. Please use e.g. Post.find_or_create_by(name: 'foo') instead."
This warning is not thrown when I run my app in development. Is FactoryGirl's code throwing this? I tried to find some information but it doesn't look like other people are getting this.
If you tell Rails to give you a full stack trace for the deprecation warning, you should be able to diagnose it pretty easily. The warnings are coming from a library called ActiveSupport::Deprecation - tell it to run in debug mode.
# config/environments/test.rb
ActiveSupport::Deprecation.debug = true
For me, the warnings were caused by an old version of the Stringex library.
FactoryGirl would make a new model, which would trigger a call to one of the Stringex methods, which would raise the warning, although there was no way to see that until I turned on full stack traces. bundle update stringex solved the issue with no problem.
It looks like it's coming from ActiveRecord.
module DeprecationWarning
def body
"#{deprecation_warning}\n#{super}"
end
def deprecation_warning
%{ActiveSupport::Deprecation.warn("This dynamic method is deprecated. Please use e.g. #{deprecation_alternative} instead.")}
end
end
I'm not sure why you're not getting the warnings in development. Is your environment suppressing the warnings?
I want to check when attributes on a model have changed. I have attempted to check values != the value on the form before doing a save but that code is really ugly and is not working well at times. Same with using update_column which does not do the validations in my model class. If I use update_attributes without doing something else I will not be able to check when a field has been updated from my understanding. From my web research on Stack Overflow and other sites it appears that using ActiveModel Dirty is the way to go.
I have looked at this: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
My hope is to use this to check if boolean flags changed on a model after using update_attributes. I attempted to do the minimum implementation as described in the included link. I added the following to my ActiveRecord class:
include ActiveModel::Dirty
define_attribute_methods [:admin]
I tried adding the three attributes I wanted to keep track of. I started with just one attribute to see if I could get it working. I received the following error when I ran an rspec test. Once I removed the argument I had no errors.
Exception encountered: #<ArgumentError: wrong number of arguments (1 for 0)>
After I removed the argument I decided to include similar methods in my model using admin instead of name. Other Rspec tests broke on the save method. However I feel the problem is with how I am implementing ActiveModel Dirty.
I have read on other Stack Overflow posts where commenters stated that this was included in 3.2.8 so I upgraded from 3.2.6 to 3.2.8. I did not understand what that meant so after getting errors I decide just to leave the include ActiveModel::Dirty statement and try to use admin_changed? Of course it did not work.
I have not been able to find anything about how to initially set things up for this other than the link I included here. All the other research I have found assumes that the initial setup was correct and that updating to the current stable version of Rails would take care of their problems.
Any help would be appreciated on how to implement this. Doing the minimal implementation as stated in the link is not working. Maybe there is something else I am missing.
The problem appears to be that ActiveRecord redefines the define_attribute_methods method to accept 0 arguments (because ActiveRecord automatically creates attribute methods for every column in the database table): https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods.rb#L23
This overrides the define_attribute_methods method provided by ActiveModel: https://github.com/rails/rails/blob/master/activemodel/lib/active_model/attribute_methods.rb#L240
Solution:
I figured out a solution that worked for me...
Save this file as lib/active_record/nonpersisted_attribute_methods.rb: https://gist.github.com/4600209
Then you can do something like this:
require 'active_record/nonpersisted_attribute_methods'
class Foo < ActiveRecord::Base
include ActiveRecord::NonPersistedAttributeMethods
define_nonpersisted_attribute_methods [:bar]
end
foo = Foo.new
foo.bar = 3
foo.bar_changed? # => true
foo.bar_was # => nil
foo.bar_change # => [nil, 3]
foo.changes[:bar] # => [nil, 3]
However, it looks like we get a warning when we do it this way:
DEPRECATION WARNING: You're trying to create an attribute `bar'. Writing arbitrary attributes on a model is deprecated. Please just use `attr_writer` etc.
So I don't know if this approach will break or be harder in Rails 4...
See also:
Track dirty for not-persisted attribute in an ActiveRecord object in rails
https://github.com/adzap/validates_timeliness/issues/73
Try adding adding =, like this:
define_attribute_methods = [:admin]
That change worked for me. Not sure if it has something to do with this?
I have statements like:
#obj[:attribute].eql?("TestValue").should be_true
And it would be nice if instead of just telling me that the test failed, it told me that it failed because #obj[:attribute] was nil or was 1234 or whatever it was. Is there any way to do this?
When doing something like
#obj.attribute.should eql(5)
and it throws an error, you'll usually see
expected 5
got 10
Is there a specific reason why you are doing eql??
Sure, rspec does output the difference between expected and actual values. You just need to change your matcher to provide more relevant information to you. Right now your expectation is that the expression #obj[:attribute].eql?("TestValue") will be true and rspec will inform you that it was false instead. If you rewrite your expectation as
#obj[:attribute].should eql("TestValue")
You should see the sort of output you are looking for.
I build several plugins using the class method 'named_scope', which has been deprecated and replaced by 'scope' in Rails 3.
I would like to avoid the following warning as I have lot a scopes present in my plugins :
DEPRECATION WARNING: Base.named_scope has been deprecated, please use Base.scope instead.
How to you deal with that? Did you create any 'scope' method if it's rails 2.X and pass the information to 'named_scope'? Any clean suggestion?
Cheers!
Vincent
Only real fix for this is to fix actual plugins outputting this error.
Just change named_scope to scope from where are you calling it.