I have a have one relationship between two models. The relationship works, the problem however is that when I write a Rspec test with shoulda matchers I get returned an error.
Failure/Error: it { should have_one(:userresetpassword)}
NameError:
uninitialized constant User::Userresetpassword
My code in the user.rb
has_one :userresetpassword
My rspec test
describe "associations" do
it { should have_one(:userresetpassword)}
end
Your association is mis-named, and either rails, shoulda-matchers or both are having a hard time guessing the class name from it.
You have two choices. First, and preferable is to rename the association to be conventional:
has_one :user_reset_password
This will allow rails to correctly guess the classname UserResetPassword
Second, you could simply remove the guesswork and tell rails what the classname is. This is only preferable if you can't or very much do not want to change the association name.
has_one :userresetpassword, :class_name => "UserResetPassword"
Related
I have a namespaced model Collection::Publication with a has_many relationship to another namespaced model Library::Publication. The association declaration looks like this:
has_many :library_publications, :dependent => :destroy, :class_name => "Library::Publication"
Yet when I try something like this:
#collection_publication.library_publications
I get this error:
NameError at /
uninitialized constant Collection::Publication::Library::Publication
It seems that Rails is namespacing the associated model, even when I explicitly define the class_name. Am I understanding this correctly? And if so, what can I do to remedy the situation?
This was due to a typo in the Library::Publication declaration:
class Libary::Publication
...
end
Although the error message declared that it wasn't finding Collection::Publication::Library::Publication, this must have been only the last place it looked. Once Library::Publication was properly defined, Rails found it without problem.
When I run a file of rspec tests on my Rails application, everything passes except the tests for has_many associations:
it { should have_many(:notes) } # ERROR
it { should belong_to(:agent_field_set) } # OK
it { should have_and_belong_to_many(:profiles) } # OK
The should have_many(:notes) line raises ArgumentError: wrong number of arguments (0 for 1). I've checked my database and my model file to verify the existance of a has_many association, and both appear fine:
has_many :notes, class_name: "NoteNs::Note", foreign_key: :user_id
Can anyone tell me where to look for the problem?
Specs: Ruby 1.9.3, Rails 3.2.11
At long last, what fixed the problem was renaming one of my named scopes. My named scope was called parent, and my model has a belongs_to :parent association.
I can't guess why a conflict arises between a named scope, being on the class, and an association, being on an instance. +1 to anyone who can explain that one to me.
I have a Mongoid model called "GradebookSettings". I've gone into inflections and added:
inflect.singular("GradebookSettings", "GradebookSettings")
When I go into irb, it properly singularizes "GradebookSettings" to "GradebookSettings". However, when I try to access an associated model, it keeps trying to singularize it to GradebookSetting.
I am using Mongoid. I am tempted to pluralize GradebookSettings with two s' but I'd rather not.
Thanks!
You don't need to trick the inflector. Use the :class_name option of the association to set the class instead:
embeds_many :gbsettings, :class_name => "GradebookSettings"
I am using Ruby on Rails to create a website for a game I play.
I have a User model and a Starbase model. The relationship I am trying to setup is like so
class User < ActiveRecord::Base
has_many :starbases
end
class Starbase < ActiveRecord::Base
belongs_to :user
end
However when I open script/console and try to access the users starbases it gives me an error: NameError: uninitialized constant User::Starbasis.
It seems as if it is a problem with inflection and rails is not pluralizing starbase correct.
I have tried adding this to the inflections.rb in the intializers folder:
ActiveSupport::Inflector.inflections do |inflect|
inflect.plural 'starbase', 'starbases'
end
but it still does not solve the issue. Could anyone give advice on how to get this working?
Have you tried adding a line for the inverse inflection (i.e. 'singular'):
inflect.singular "starbases", "starbase"
I tried your example in my console and it was the singularization that caused problems, not the other way around. I'm not sure if this fixes other issues (like routes), but it should fix the simple stuff (I think).
Little trick i picked up to double check how Active Support might singularize, or pluralize my Class names, and/or Module names.
have your rails app server running and in a new tab enter into your rails console by typing rails console. In there you can easily double check for the correct style for your names.
long way ActiveSupport::Inflector.pluralize "fish"
# => "fish"
short way "fish".pluralize
# => "fish"
You can find more examples here
https://github.com/rails/rails/blob/master/activesupport/test/inflector_test_cases.rb
I am learning how to write test cases using Rspec. I have a simple Post Comments Scaffold where a Post can have many Comments. I am testing this using Rspec. How should i go about checking for Post :has_many :comments. Should I stub Post.comments method and then check this with by returning a mock object of array of comment objects? Is testing for AR associations really required ?
Since ActiveRecord associations should be well-tested by the Rails test suite (and they are), most people don't feel the need to make sure they work -- it's just assumed that they will.
If you want to make sure that your model is using those associations, that's something different, and you're not wrong for wanting to test that. I like to do this using the shoulda gem. It lets you do neat things like this:
describe Post do
it { should have_many(:comments).dependent(:destroy) }
end
Testing associations is good practice generally, especially in an environment where TDD is highly regarded- other developers will often look to your specs before looking at the corresponding code. Testing associations makes sure that your spec file most accurately reflects your code.
Two ways you can test associations:
With FactoryGirl:
expect { FactoryGirl.create(:post).comments }.to_not raise_error
This is a relatively superficial test that will, with a factory like:
factory :post do
title { "Top 10 Reasons why Antelope are Nosy Creatures" }
end
return you a NoMethodError if your model lacks a has_many association with comments.
You can use the ActiveRecord #reflect_on_association method to take a more in-depth look at your association. For instance, with a more complex association:
class Post
has_many :comments, through: :user_comments, source: :commentary
end
You can take a deeper look into your association:
reflection = Post.reflect_on_association(:comment)
reflection.macro.should eq :has_many
reflection.options[:through].should eq :user_comments
reflection.options[:source].should eq :commentary
and test on whatever options or conditions are relevant.
If you'd rather not use an external gem like shoulda to test your associations (see Robert Speicher's Answer for details on that), another option is to use reflect_on_association to get the AssociationReflection object for the relevant association, and then assert on that:
describe Post do
it "should destroy its comments when it is destroyed" do
association = Post.reflect_on_association(:comments)
expect(association).to_not be_nil
expect(association.options[:dependent]).to eq :destroy
end
end
Most people don't test the associations, as Rails already has unit tests to make sure those methods work correctly. If you are doing something complex, like involving a proc or something, you might want to explicitly test it. Usually you can do this by just doing
a = Post.new
a.comments << Comment.new
assert a.save
assert a.comments.size == 1
or something akin to that.